[PATCH] Xorg in a jail
Tom Evans
tevans.uk at googlemail.com
Sun Mar 9 01:26:43 UTC 2014
I've been reinstalling my home server with 10-STABLE and wanted to
compartmentalise all the disparate tasks it does - file storage, DNS,
web servers and mplayer/xorg/media stuff in general - in to a separate
jail for each task.
For the most part, this was quite straightforward, apart from with
xorg I found that it wasn't quite supported. I found Alexander's
patch, and the work Jamie did in part integrating it, allowing kmem
read, and reworked it for 10-STABLE.
>From Jamie's emails it looked like he was working on a way of properly
integrating these permissions in a more unified way, but I had a
pressing need :)
I've tested this on 10-STABLE r262457M, intel graphics (ivy bridge,
WITH_NEW_XORG), and everything seems to work just fine. I'm going to
try out radeonkms and nvidia tomorrow also.
Also please note that whilst I want things jailed for separation and
neatness concerns rather than security, it must be pointed out that
letting one jail read and write kernel memory of the whole machine is
not at all secure! Anyone with root in this xorg jail would be able to
break free of the jail.
I'm not sure I did the jail allow parameters right, but it works for
me - I would appreciate someone more competent taking a look! Also,
dev_io_access should probably be renamed or using it to control access
to /dev/mem split out from it? Also, is the style right? vim: noet
sw=8 ts=8 is what I was using.
Cheers
Tom
PS: I haven't tested any input devices yet with this, let me know!
Instructions:
Apply patch, rebuild world and kernel, install and update jails/basejails
Create /etc/devfs.rules to unhide the pertinent devices and restart devfs
This is what I am using, it might be overkill...
[devfsrules_unhide_xorg=8]
add include $devfsrules_hide_all
add include $devfsrules_unhide_basic
add include $devfsrules_unhide_login
add path agpgart unhide
add path console unhide
add path consolectl unhide
add path dri unhide
add path 'dri/*' unhide
add path io unhide
add path mem unhide
add path pci unhide
add path tty unhide
add path ttyv0 unhide
add path ttyv1 unhide
add path ttyv8 unhide
Set sysctls on jail host to allow jails to have permission granted to
them to access (in particular) /dev/mem, /dev/io and /dev/dri/*
security.jail.dev_io_access=1
security.jail.dev_dri_access=1
Configure your chosen jail to use these devfs rules and allow them to
use the devices. I use ezjail, so for me this meant changing
/usr/local/etc/ezjail/<name_of_jail> and setting these lines:
export jail_xorg_foo_com_devfs_ruleset="8"
export jail_xorg_foo_com_parameters="allow.dev_io_access=1
allow.dev_dri_access=1"
Load any required kernel modules in the jail host - xorg in the jail
will not be able to load them for you. Therefore, make sure to load
i915kms, radeonkms or nvidia before hand.
Install and use xorg in the jail as you would normally.
-------------- next part --------------
Index: sys/dev/drm/drmP.h
===================================================================
--- sys/dev/drm/drmP.h (revision 262457)
+++ sys/dev/drm/drmP.h (working copy)
@@ -228,7 +228,7 @@
#define PAGE_ALIGN(addr) round_page(addr)
/* DRM_SUSER returns true if the user is superuser */
#if __FreeBSD_version >= 700000
-#define DRM_SUSER(p) (priv_check(p, PRIV_DRIVER) == 0)
+#define DRM_SUSER(p) (priv_check(p, PRIV_DRI_DRIVER) == 0)
#else
#define DRM_SUSER(p) (suser(p) == 0)
#endif
Index: sys/dev/drm2/drmP.h
===================================================================
--- sys/dev/drm2/drmP.h (revision 262457)
+++ sys/dev/drm2/drmP.h (working copy)
@@ -251,7 +251,7 @@
#define PAGE_ALIGN(addr) round_page(addr)
/* DRM_SUSER returns true if the user is superuser */
-#define DRM_SUSER(p) (priv_check(p, PRIV_DRIVER) == 0)
+#define DRM_SUSER(p) (priv_check(p, PRIV_DRI_DRIVER) == 0)
#define DRM_AGP_FIND_DEVICE() agp_find_device()
#define DRM_MTRR_WC MDF_WRITECOMBINE
#define jiffies ticks
Index: sys/kern/kern_jail.c
===================================================================
--- sys/kern/kern_jail.c (revision 262457)
+++ sys/kern/kern_jail.c (working copy)
@@ -207,6 +207,8 @@
"allow.mount.zfs",
"allow.mount.procfs",
"allow.mount.tmpfs",
+ "allow.dev_io_access",
+ "allow.dev_dri_access",
};
const size_t pr_allow_names_size = sizeof(pr_allow_names);
@@ -223,6 +225,8 @@
"allow.mount.nozfs",
"allow.mount.noprocfs",
"allow.mount.notmpfs",
+ "allow.nodev_io_access",
+ "allow.nodev_dri_access",
};
const size_t pr_allow_nonames_size = sizeof(pr_allow_nonames);
@@ -3950,6 +3954,27 @@
return (0);
/*
+ * Allow access to /dev/io in a jail if the non-jailed admin
+ * requests this and if /dev/io exists in the jail. This
+ * allows Xorg to probe a card.
+ */
+ case PRIV_IO:
+ case PRIV_KMEM_WRITE:
+ if (cred->cr_prison->pr_allow & PR_ALLOW_DEV_IO_ACCESS)
+ return (0);
+ else
+ return (EPERM);
+
+ /*
+ * Allow low level access to DRI. This allows Xorgs to use DRI.
+ */
+ case PRIV_DRI_DRIVER:
+ if (cred->cr_prison->pr_allow & PR_ALLOW_DEV_DRI_ACCESS)
+ return (0);
+ else
+ return (EPERM);
+
+ /*
* Allow jailed root to set loginclass.
*/
case PRIV_PROC_SETLOGINCLASS:
@@ -4246,6 +4271,15 @@
NULL, PR_ALLOW_MOUNT_ZFS, sysctl_jail_default_allow, "I",
"Processes in jail can mount the zfs file system");
+SYSCTL_PROC(_security_jail, OID_AUTO, dev_io_access,
+ CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_MPSAFE,
+ NULL, PR_ALLOW_DEV_IO_ACCESS, sysctl_jail_default_allow, "I",
+ "Processes in jail can access /dev/io if it exists");
+SYSCTL_PROC(_security_jail, OID_AUTO, dev_dri_access,
+ CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_MPSAFE,
+ NULL, PR_ALLOW_DEV_DRI_ACCESS, sysctl_jail_default_allow, "I",
+ "Processes in jail can access /dev/dri if it exists");
+
static int
sysctl_jail_default_level(SYSCTL_HANDLER_ARGS)
{
@@ -4383,6 +4417,10 @@
"B", "Jail may set file quotas");
SYSCTL_JAIL_PARAM(_allow, socket_af, CTLTYPE_INT | CTLFLAG_RW,
"B", "Jail may create sockets other than just UNIX/IPv4/IPv6/route");
+SYSCTL_JAIL_PARAM(_allow, dev_io_access, CTLTYPE_INT | CTLFLAG_RW,
+ "B", "Jail may access /dev/io if it exists");
+SYSCTL_JAIL_PARAM(_allow, dev_dri_access, CTLTYPE_INT | CTLFLAG_RW,
+ "B", "Jail may access /dev/dri if it exists");
SYSCTL_JAIL_PARAM_SUBNODE(allow, mount, "Jail mount/unmount permission flags");
SYSCTL_JAIL_PARAM(_allow_mount, , CTLTYPE_INT | CTLFLAG_RW,
Index: sys/sys/jail.h
===================================================================
--- sys/sys/jail.h (revision 262457)
+++ sys/sys/jail.h (working copy)
@@ -228,7 +228,9 @@
#define PR_ALLOW_MOUNT_ZFS 0x0200
#define PR_ALLOW_MOUNT_PROCFS 0x0400
#define PR_ALLOW_MOUNT_TMPFS 0x0800
-#define PR_ALLOW_ALL 0x0fff
+#define PR_ALLOW_DEV_IO_ACCESS 0x1000
+#define PR_ALLOW_DEV_DRI_ACCESS 0x2000
+#define PR_ALLOW_ALL 0x3fff
/*
* OSD methods
Index: sys/sys/priv.h
===================================================================
--- sys/sys/priv.h (revision 262457)
+++ sys/sys/priv.h (working copy)
@@ -500,10 +500,11 @@
#define PRIV_KMEM_READ 680 /* Open mem/kmem for reading. */
#define PRIV_KMEM_WRITE 681 /* Open mem/kmem for writing. */
+#define PRIV_DRI_DRIVER 682
/*
* Track end of privilege list.
*/
-#define _PRIV_HIGHEST 682
+#define _PRIV_HIGHEST 683
/*
* Validate that a named privilege is known by the privilege system. Invalid
More information about the freebsd-x11
mailing list