> Date: Wed, 12 Dec 2018 01:27:24 +0200
> From: Lauri Tirkkonen <[email protected]>
> 
> Hi,
> 
> since the Xorg setuid bit was removed, I looked a little bit into what
> it would take to run it without root privs. I have a proof of concept
> put together, and things seem to work (on an X220 amd64 + modesetting
> driver, inteldrm; login on ttyC0 and running xinit).  Testing the waters
> here to see if anyone else is interested :)

I have a somewhat similar set of diffs that still need some polishing.
I have not been able to push that forward the last couple of weeks
because of lack of time.  But I hope that'll change after next
weekend.

> First, we need Xorg to attempt xf86OpenConsole even when we're not uid
> 0. That will call xf86OpenWScons (through xf86ConsTab), which opens the
> console device and does wscons ioctls on it -- succeeding if the user
> running X has logged in on that console.
> 
> diff --git a/xserver/hw/xfree86/common/xf86Init.c 
> b/xserver/hw/xfree86/common/xf86Init.c
> index 2a04da045..b814eb412 100644
> --- a/xserver/hw/xfree86/common/xf86Init.c
> +++ b/xserver/hw/xfree86/common/xf86Init.c
> @@ -967,9 +967,13 @@ OsVendorInit(void)
>  #endif
>  #endif
>  #if defined(X_PRIVSEP)
> -  if (!beenHere && !xf86KeepPriv && geteuid() == 0) {
> -       xf86PrivilegedInit();
> -       xf86DropPriv();
> +  if (!beenHere) {
> +       if(!xf86KeepPriv && geteuid() == 0) {
> +               xf86PrivilegedInit();
> +               xf86DropPriv();
> +       } else {
> +               xf86OpenConsole();
> +       }
>    }
>  #endif
>  
> 
> Next, we need the user logging in on ttyC0 to be able to access
> /dev/pci0 and /dev/ttyC4:
> 
> diff --git a/etc/etc.amd64/fbtab b/etc/etc.amd64/fbtab
> index 79cfb535c9f..b746b7684f7 100644
> --- a/etc/etc.amd64/fbtab
> +++ b/etc/etc.amd64/fbtab
> @@ -1 +1 @@
> -/dev/ttyC0   0600    
> /dev/console:/dev/wskbd:/dev/wskbd0:/dev/wsmouse:/dev/wsmouse0:/dev/ttyCcfg:/dev/drm0
> +/dev/ttyC0   0600    
> /dev/console:/dev/wskbd:/dev/wskbd0:/dev/wsmouse:/dev/wsmouse0:/dev/ttyCcfg:/dev/drm0:/dev/pci0:/dev/ttyC4
> 
> 
> Finally, there's a check in drm_drv.c that only allows superuser to
> become a master on /dev/drm0 and fails the open for other users. I
> removed the superuser check; filesystem permissions should prevent
> anyone except the user logging in on ttyC0 from accessing this device
> anyway. I haven't studied what exactly being the master allows here and
> if there's possible privilege escalation hiding there; my reading of
> drm_do_ioctl is that ioctls marked DRM_ROOT_ONLY will still fail, so I
> admit I don't really know what the check was there for...
> 
> Still, this allows running X without any user processes as root (and
> unbreaks xinit/startx) - is there any potential here? :)
> 
> diff --git a/sys/dev/pci/drm/drm_drv.c b/sys/dev/pci/drm/drm_drv.c
> index e09380e3257..be9773b0671 100644
> --- a/sys/dev/pci/drm/drm_drv.c
> +++ b/sys/dev/pci/drm/drm_drv.c
> @@ -745,14 +745,10 @@ drmopen(dev_t kdev, int flags, int fmt, struct proc *p)
>       }
>  
>       mutex_lock(&dev->struct_mutex);
> -     /* first opener automatically becomes master if root */
> -     if (SPLAY_EMPTY(&dev->files) && !DRM_SUSER(p)) {
> -             mutex_unlock(&dev->struct_mutex);
> -             ret = EPERM;
> -             goto free_priv;
> -     }
> -
> +     /* first opener automatically becomes master */
>       file_priv->is_master = SPLAY_EMPTY(&dev->files);
> +     if (!file_priv->authenticated)
> +             file_priv->authenticated = file_priv->is_master;
>  
>       SPLAY_INSERT(drm_file_tree, &dev->files, file_priv);
>       mutex_unlock(&dev->struct_mutex);
> 
> -- 
> Lauri Tirkkonen | lotheac @ IRCnet
> 
> 

Reply via email to