> 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
>
>