diff options
author | 2016-01-06 09:09:16 +0000 | |
---|---|---|
committer | 2016-01-06 09:09:16 +0000 | |
commit | f6b590bc696749d85aad6a323b5989cc0c9ed222 (patch) | |
tree | 334a929ce1156969357425302ed9cb0f8d47b36e | |
parent | deactivate POOL_DEBUG for release (diff) | |
download | wireguard-openbsd-f6b590bc696749d85aad6a323b5989cc0c9ed222.tar.xz wireguard-openbsd-f6b590bc696749d85aad6a323b5989cc0c9ed222.zip |
Add pledge "drm", which allows a subset of the drm(4) ioctls. These are
basically only the ioctls that Linux allows on the so-called "render nodes".
For now, it also allows DRM_IOCTL_GET_MAGIC and DRM_IOCTL_GEM_OPEN, as we
don't implement prime/dma-buf yet in OpenBSD. That still leaves a big gaping
hole, so they will be removed as soon as we can.
Based on a diff by robert@, who did all the heavy lifting by studying the
behaviour of the chromium GPU process, with some further suggestions by
deraadt@.
ok jsg@, deraadt@, robert@
-rw-r--r-- | sys/dev/pci/drm/drm_drv.c | 38 | ||||
-rw-r--r-- | sys/kern/kern_pledge.c | 23 | ||||
-rw-r--r-- | sys/sys/conf.h | 3 | ||||
-rw-r--r-- | sys/sys/pledge.h | 5 |
4 files changed, 64 insertions, 5 deletions
diff --git a/sys/dev/pci/drm/drm_drv.c b/sys/dev/pci/drm/drm_drv.c index 867f8c56373..d5d8a4fa761 100644 --- a/sys/dev/pci/drm/drm_drv.c +++ b/sys/dev/pci/drm/drm_drv.c @@ -1,4 +1,4 @@ -/* $OpenBSD: drm_drv.c,v 1.142 2015/12/31 13:01:00 kettenis Exp $ */ +/* $OpenBSD: drm_drv.c,v 1.143 2016/01/06 09:09:16 kettenis Exp $ */ /*- * Copyright 2007-2009 Owain G. Ainsworth <oga@openbsd.org> * Copyright © 2008 Intel Corporation @@ -44,6 +44,7 @@ #include <sys/fcntl.h> #include <sys/filio.h> #include <sys/limits.h> +#include <sys/pledge.h> #include <sys/poll.h> #include <sys/specdev.h> #include <sys/systm.h> @@ -246,6 +247,41 @@ static struct drm_ioctl_desc drm_ioctls[] = { #define DRM_CORE_IOCTL_COUNT ARRAY_SIZE( drm_ioctls ) int +pledge_ioctl_drm(struct proc *p, long com, dev_t device) +{ + struct drm_device *dev = drm_get_device_from_kdev(device); + unsigned int nr = DRM_IOCTL_NR(com); + const struct drm_ioctl_desc *ioctl; + + if (dev == NULL) + return EPERM; + + if (nr < DRM_CORE_IOCTL_COUNT && + ((nr < DRM_COMMAND_BASE || nr >= DRM_COMMAND_END))) + ioctl = &drm_ioctls[nr]; + else if (nr >= DRM_COMMAND_BASE && nr < DRM_COMMAND_END && + nr < DRM_COMMAND_BASE + dev->driver->num_ioctls) + ioctl = &dev->driver->ioctls[nr - DRM_COMMAND_BASE]; + else + return EPERM; + + if (ioctl->flags & DRM_RENDER_ALLOW) + return 0; + + /* + * These are dangerous, but we have to allow them until we + * have prime/dma-buf support. + */ + switch (com) { + case DRM_IOCTL_GET_MAGIC: + case DRM_IOCTL_GEM_OPEN: + return 0; + } + + return EPERM; +} + +int drm_setunique(struct drm_device *dev, void *data, struct drm_file *file_priv) { diff --git a/sys/kern/kern_pledge.c b/sys/kern/kern_pledge.c index 4323a6b9e86..89808cd1178 100644 --- a/sys/kern/kern_pledge.c +++ b/sys/kern/kern_pledge.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kern_pledge.c,v 1.141 2016/01/05 18:09:24 deraadt Exp $ */ +/* $OpenBSD: kern_pledge.c,v 1.142 2016/01/06 09:09:16 kettenis Exp $ */ /* * Copyright (c) 2015 Nicholas Marriott <nicm@openbsd.org> @@ -67,6 +67,11 @@ #include "audio.h" #include "pty.h" +#if defined(__amd64__) || defined(__i386__) || \ + defined(__macppc__) || defined(__sparc64__) +#include "drm.h" +#endif + int pledgereq_flags(const char *req); int canonpath(const char *input, char *buf, size_t bufsize); int substrcmp(const char *p1, size_t s1, const char *p2, size_t s2); @@ -338,6 +343,7 @@ static const struct { { "disklabel", PLEDGE_DISKLABEL }, { "dns", PLEDGE_DNS }, { "dpath", PLEDGE_DPATH }, + { "drm", PLEDGE_DRM }, { "exec", PLEDGE_EXEC }, { "fattr", PLEDGE_FATTR }, { "flock", PLEDGE_FLOCK }, @@ -1123,6 +1129,7 @@ int pledge_ioctl(struct proc *p, long com, struct file *fp) { struct vnode *vp = NULL; + int error = EPERM; if ((p->p_p->ps_flags & PS_PLEDGE) == 0) return (0); @@ -1174,6 +1181,18 @@ pledge_ioctl(struct proc *p, long com, struct file *fp) } } + if ((p->p_p->ps_pledge & PLEDGE_DRM)) { +#if NDRM > 0 + if ((fp->f_type == DTYPE_VNODE) && + (vp->v_type == VCHR) && + (cdevsw[major(vp->v_rdev)].d_open == drmopen)) { + error = pledge_ioctl_drm(p, com, vp->v_rdev); + if (error == 0) + return 0; + } +#endif /* NDRM > 0 */ + } + if ((p->p_p->ps_pledge & PLEDGE_AUDIO)) { #if NAUDIO > 0 switch (com) { @@ -1306,7 +1325,7 @@ pledge_ioctl(struct proc *p, long com, struct file *fp) } } - return pledge_fail(p, EPERM, PLEDGE_IOCTL); + return pledge_fail(p, error, PLEDGE_IOCTL); } int diff --git a/sys/sys/conf.h b/sys/sys/conf.h index a44b3c2eee9..9be9b67750e 100644 --- a/sys/sys/conf.h +++ b/sys/sys/conf.h @@ -1,4 +1,4 @@ -/* $OpenBSD: conf.h,v 1.135 2015/10/23 15:10:52 claudio Exp $ */ +/* $OpenBSD: conf.h,v 1.136 2016/01/06 09:09:16 kettenis Exp $ */ /* $NetBSD: conf.h,v 1.33 1996/05/03 20:03:32 christos Exp $ */ /*- @@ -529,6 +529,7 @@ cdev_decl(ptm); cdev_decl(ctty); cdev_decl(audio); +cdev_decl(drm); cdev_decl(midi); cdev_decl(radio); cdev_decl(video); diff --git a/sys/sys/pledge.h b/sys/sys/pledge.h index f01dd90a65b..cd261ec3929 100644 --- a/sys/sys/pledge.h +++ b/sys/sys/pledge.h @@ -1,4 +1,4 @@ -/* $OpenBSD: pledge.h,v 1.24 2015/12/06 17:50:21 deraadt Exp $ */ +/* $OpenBSD: pledge.h,v 1.25 2016/01/06 09:09:16 kettenis Exp $ */ /* * Copyright (c) 2015 Nicholas Marriott <nicm@openbsd.org> @@ -55,6 +55,7 @@ #define PLEDGE_PF 0x0000000004000000ULL /* pf ioctls */ #define PLEDGE_AUDIO 0x0000000008000000ULL /* audio ioctls */ #define PLEDGE_DPATH 0x0000000010000000ULL /* mknod & mkfifo */ +#define PLEDGE_DRM 0x0000000020000000ULL /* drm ioctls */ /* * Bits outside PLEDGE_USERSET are used by the kernel itself @@ -98,6 +99,7 @@ static struct { { PLEDGE_PF, "pf" }, { PLEDGE_AUDIO, "audio" }, { PLEDGE_DPATH, "dpath" }, + { PLEDGE_DRM, "drm" }, { 0, NULL }, }; #endif @@ -119,6 +121,7 @@ int pledge_sendit(struct proc *p, const void *to); int pledge_sockopt(struct proc *p, int set, int level, int optname); int pledge_socket(struct proc *p, int domain, int state); int pledge_ioctl(struct proc *p, long com, struct file *); +int pledge_ioctl_drm(struct proc *p, long com, dev_t device); int pledge_flock(struct proc *p); int pledge_fcntl(struct proc *p, int cmd); int pledge_swapctl(struct proc *p); |