On Thu, May 24, 2018 at 07:15:05PM +0200, Landry Breuil wrote:
> Hi,
> 
> here's two simple diffs (one for the kernel, one for the pledge.2
> manpage) that allow me to use my webcam again within firefox when
> pledged,, adding 'video' to the main process pledges.
> 
> The kernel changes are similar to what was done for 'audio' pledge, and
> i took the ioctl list from the ones found in the mozilla codebase:
> https://dxr.mozilla.org/mozilla-central/search?q=vidioc&redirect=false
> 
> Comments and feedback welcome. Of course, to test it using firefox, you
> still need to grant your user access to /dev/video*.

After having been poked offline about why this diff hadnt been commited,
sending an updated diff including the pledge.h change, and updated after unveil
addition. Among other bits, you'll need this if you want to use webrtc in
firefox while being still pledged - the other solution right now is of course
disabling pledge, which is a pity.

I went over this for a while and i don't see how firefox could be adapted to
avoid this new pledge class. The other option is to move lots of code around so
that the video device is opened/configured inconditionally by the main process
before pledging (but then you'd still need the various ioctls getting buffers
etc), but that feels stupid: why would you want to open the video device if
you're not going to actually use it ?

Right now the devices are listed/opened *when* camera access is requested by
a page aiming to use the camera, ie during the process lifetime, so until
upstream decides to separate video device access in a separate process (which
isnt afaik on the radar) adding this pledge class is the only solution i see
for now.

That of course doesn't try to solve the video device access/ownership which is
a separate issue.

Feedback appreciated.

Index: sys/pledge.h
===================================================================
RCS file: /cvs/src/sys/sys/pledge.h,v
retrieving revision 1.37
diff -u -r1.37 pledge.h
--- sys/pledge.h        13 Jul 2018 09:25:23 -0000      1.37
+++ sys/pledge.h        25 Jul 2018 17:59:15 -0000
@@ -62,6 +62,7 @@
 #define PLEDGE_ERROR   0x0000000400000000ULL   /* ENOSYS instead of kill */
 #define PLEDGE_WROUTE  0x0000000800000000ULL   /* interface address ioctls */
 #define PLEDGE_UNVEIL  0x0000001000000000ULL   /* allow unveil() */
+#define PLEDGE_VIDEO   0x0000002008000000ULL   /* video ioctls */
 
 /*
  * Bits outside PLEDGE_USERSET are used by the kernel itself
@@ -112,6 +113,7 @@
        { PLEDGE_ERROR,         "error" },
        { PLEDGE_WROUTE,        "wroute" },
        { PLEDGE_UNVEIL,        "unveil" },
+       { PLEDGE_VIDEO,         "video" },
        { 0, NULL },
 };
 #endif
Index: kern/kern_pledge.c
===================================================================
RCS file: /cvs/src/sys/kern/kern_pledge.c,v
retrieving revision 1.237
diff -u -r1.237 kern_pledge.c
--- kern/kern_pledge.c  15 Jul 2018 12:44:09 -0000      1.237
+++ kern/kern_pledge.c  25 Jul 2018 17:59:15 -0000
@@ -43,6 +43,7 @@
 #include <sys/dkio.h>
 #include <sys/mtio.h>
 #include <sys/audioio.h>
+#include <sys/videoio.h>
 #include <net/bpf.h>
 #include <net/route.h>
 #include <net/if.h>
@@ -396,6 +397,7 @@
        { "tty",                PLEDGE_TTY },
        { "unix",               PLEDGE_UNIX },
        { "unveil",             PLEDGE_UNVEIL },
+       { "video",              PLEDGE_VIDEO },
        { "vminfo",             PLEDGE_VMINFO },
        { "vmm",                PLEDGE_VMM },
        { "wpath",              PLEDGE_WPATH },
@@ -1151,6 +1153,30 @@
                        break;
                }
        }
+
+       if ((p->p_p->ps_pledge & PLEDGE_VIDEO)) {
+               switch (com) {
+               case VIDIOC_QUERYCAP:
+               case VIDIOC_ENUM_FMT:
+               case VIDIOC_S_FMT:
+               case VIDIOC_G_PARM:
+               case VIDIOC_S_PARM:
+               case VIDIOC_REQBUFS:
+               case VIDIOC_QBUF:
+               case VIDIOC_DQBUF:
+               case VIDIOC_QUERYBUF:
+               case VIDIOC_STREAMON:
+               case VIDIOC_STREAMOFF:
+               case VIDIOC_ENUM_FRAMESIZES:
+               case VIDIOC_ENUM_FRAMEINTERVALS:
+                       if (fp->f_type == DTYPE_VNODE &&
+                           vp->v_type == VCHR &&
+                           cdevsw[major(vp->v_rdev)].d_open == videoopen)
+                               return (0);
+                       break;
+               }
+       }
+
 
 #if NPF > 0
        if ((p->p_p->ps_pledge & PLEDGE_PF)) {

Reply via email to