The perennial Xorg inside jails patch

Brian Cully

New Member


Messages: 5

I've modified the patch I found on these fora to allow /dev/kmem write access inside jails. The security arguments are hopefully well known: there isn't any. It's still useful for me in order to test different Xorg configs, desktop environments, and ports trees without potentially screwing up the host. I've been using this patch for months now and haven't had any stability issues.

To use the facility, you need to set 'allow.dev_kmem' in your jail config. In addition, for a full-featured Xorg, you need a bunch of devices in devfs.rules:

Code:
#
# Nicked from https://www.bsdstore.ru/en/xorg_in_jail.html
#
[unhide_xorg=8]
add include $devfsrules_hide_all
add include $devfsrules_unhide_basic
add include $devfsrules_unhide_login
add include $operator_usb
add path agpgart unhide
add path console unhide
add path consolectl unhide
add path dri unhide
add path 'dri/*' unhide
add path 'dri/card*' unhide
add path drm unhide
add path 'drm/*' unhide
add path 'sndstat' unhide
add path 'dsp*' unhide
add path 'mixer*' unhide
add path 'sequencer*' unhide
add path io unhide
add path sysmouse unhide
add path mem unhide
add path pci unhide
add path tty unhide
add path ttyv0 unhide
add path ttyv1 unhide
add path ttyv2 unhide
add path ttyv8 unhide
add path fuse unhide
add path usbctl unhide
add path usb unhide
add path 'usb/*' unhide
add path 'ugen*' unhide
add path 'da*' unhide
add path 'cua*' unhide
add path input unhide
add path 'input/*' unhide
Patch is below. FWIW, this patch is even simpler than previous ones, so maybe there's some hope that this functionality will be in mainline at some point, but maybe I'm just reading into things.

Code:
commit fb7bb3c26bf2fdd86c8bfc6c6e3621dd89d51b29
Author: Brian Cully <bjc@kublai.com>
Date:   Thu Nov 22 04:07:06 2018 -0500

    Allow /dev/kmem write access inside jails with appropriate jail config.
    
    When a jail is configured with 'allow.dev_kmem' that jail is allowed
    write access to kernel memory (assuming the device exists in /dev).
    
    There are obvious security ramifications for allowing jails to do
    this: basically, there is no isolation from within the jail and it can
    do whatever it wants on the host or within any jail. Be careful using
    it.

diff --git a/sys/kern/kern_jail.c b/sys/kern/kern_jail.c
index 35564477f00..2da9702a51e 100644
--- a/sys/kern/kern_jail.c
+++ b/sys/kern/kern_jail.c
@@ -194,6 +194,7 @@ static struct bool_flags pr_flag_allow[NBBY * NBPW] = {
        {"allow.reserved_ports", "allow.noreserved_ports",
         PR_ALLOW_RESERVED_PORTS},
        {"allow.read_msgbuf", "allow.noread_msgbuf", PR_ALLOW_READ_MSGBUF},
+        {"allow.dev_kmem", "allow.nodev_kmem", PR_ALLOW_KMEM_ACCESS},
 };
 const size_t pr_flag_allow_size = sizeof(pr_flag_allow);
 
@@ -3361,6 +3362,21 @@ prison_priv_check(struct ucred *cred, int priv)
                        return (0);
                return (EPERM);
 
+                /*
+                 * Allow write access to /dev/mem if the non-jailed admin
+                 * requests it and /dev/mem exists in the jail. This is
+                 * very unsafe, as it violates literally any possible
+                 * security benefits of the jail, but it's useful for
+                 * allowing DRM within a jail.
+                 */
+        case PRIV_DRIVER:
+        case PRIV_IO:
+        case PRIV_KMEM_WRITE:
+               if (cred->cr_prison->pr_allow & PR_ALLOW_KMEM_ACCESS)
+                       return (0);
+               else
+               return (EPERM);
+
        default:
                /*
                 * In all remaining cases, deny the privilege request.  This
@@ -3631,6 +3647,11 @@ SYSCTL_PROC(_security_jail, OID_AUTO, mount_allowed,
     CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_MPSAFE,
     NULL, PR_ALLOW_MOUNT, sysctl_jail_default_allow, "I",
     "Processes in jail can mount/unmount jail-friendly file systems (deprecated)");
+SYSCTL_PROC(_security_jail, OID_AUTO, dev_kmem_access,
+    CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_MPSAFE,
+    NULL, PR_ALLOW_KMEM_ACCESS, sysctl_jail_default_allow, "I",
+    "Proccess in jail can write to /dev/kmem if it exists");
+
 
 static int
 sysctl_jail_default_level(SYSCTL_HANDLER_ARGS)
@@ -3783,6 +3804,8 @@ SYSCTL_JAIL_PARAM(_allow, reserved_ports, CTLTYPE_INT | CTLFLAG_RW,
     "B", "Jail may bind sockets to reserved ports");
 SYSCTL_JAIL_PARAM(_allow, read_msgbuf, CTLTYPE_INT | CTLFLAG_RW,
     "B", "Jail may read the kernel message buffer");
+SYSCTL_JAIL_PARAM(_allow, dev_kmem, CTLTYPE_INT | CTLFLAG_RW,
+    "B", "Jail may write to /dev/kmem");
 
 SYSCTL_JAIL_PARAM_SUBNODE(allow, mount, "Jail mount/unmount permission flags");
 SYSCTL_JAIL_PARAM(_allow_mount, , CTLTYPE_INT | CTLFLAG_RW,
 
Top