On Mon, Jul 30, 2018 at 07:55:35AM -0600, Bob Beck wrote:
> yeah the latter will be the way to go
>

here it is.

Some notes:
- I changed flags definition from uint64_t to int
- I defined `static inline' the function that do the conversion from
  pledge to unveil: having a function is more readable, but it is called
  often (for checking each compoment)

thanks.
-- 
Sebastien Marie

Index: sys/proc.h
===================================================================
RCS file: /cvs/src/sys/sys/proc.h,v
retrieving revision 1.254
diff -u -p -r1.254 proc.h
--- sys/proc.h  28 Jul 2018 18:07:26 -0000      1.254
+++ sys/proc.h  30 Jul 2018 15:27:22 -0000
@@ -130,7 +130,7 @@ struct tusage {
 struct unvname {
        char                    *un_name;
        size_t                  un_namesize;
-       uint64_t                un_flags;
+       int                     un_flags;
        RBT_ENTRY(unvnmae)      un_rbt;
 };
 
@@ -424,7 +424,7 @@ struct unveil {
        struct vnode            *uv_vp;
        struct unvname_rbt      uv_names;
        struct rwlock           uv_lock;
-       u_int64_t               uv_flags;
+       int                     uv_flags;
 };
 
 struct uidinfo {
Index: kern/kern_unveil.c
===================================================================
RCS file: /cvs/src/sys/kern/kern_unveil.c,v
retrieving revision 1.9
diff -u -p -r1.9 kern_unveil.c
--- kern/kern_unveil.c  30 Jul 2018 15:16:27 -0000      1.9
+++ kern/kern_unveil.c  30 Jul 2018 17:40:07 -0000
@@ -40,6 +40,11 @@
 #define UNVEIL_MAX_VNODES      128
 #define UNVEIL_MAX_NAMES       128
 
+#define        UNVEIL_READ     0x01
+#define        UNVEIL_WRITE    0x02
+#define        UNVEIL_EXEC     0x04
+#define        UNVEIL_CREATE   0x08
+
 static inline int
 unvname_compare(const struct unvname *n1, const struct unvname *n2)
 {
@@ -50,7 +55,7 @@ unvname_compare(const struct unvname *n1
 }
 
 struct unvname *
-unvname_new(const char *name, size_t size, uint64_t flags)
+unvname_new(const char *name, size_t size, int flags)
 {
        struct unvname *ret = malloc(sizeof(struct unvname), M_PROC, M_WAITOK);
        ret->un_name = malloc(size, M_PROC, M_WAITOK);
@@ -118,7 +123,7 @@ unveil_delete_names(struct unveil *uv)
 }
 
 void
-unveil_add_name(struct unveil *uv, char *name, uint64_t flags)
+unveil_add_name(struct unveil *uv, char *name, int flags)
 {
        struct unvname *unvn;
 
@@ -310,7 +315,7 @@ unveil_lookup(struct vnode *vp, struct p
 }
 
 int
-unveil_parsepermissions(const char *permissions, uint64_t *perms)
+unveil_parsepermissions(const char *permissions, int *perms)
 {
        size_t i = 0;
        char c;
@@ -319,16 +324,16 @@ unveil_parsepermissions(const char *perm
        while ((c = permissions[i++]) != '\0') {
                switch (c) {
                case 'r':
-                       *perms |= PLEDGE_RPATH;
+                       *perms |= UNVEIL_READ;
                        break;
                case 'w':
-                       *perms |= PLEDGE_WPATH;
+                       *perms |= UNVEIL_WRITE;
                        break;
                case 'x':
-                       *perms |= PLEDGE_EXEC;
+                       *perms |= UNVEIL_EXEC;
                        break;
                case 'c':
-                       *perms |= PLEDGE_CPATH;
+                       *perms |= UNVEIL_CREATE;
                        break;
                default:
                        return -1;
@@ -338,7 +343,7 @@ unveil_parsepermissions(const char *perm
 }
 
 int
-unveil_setflags(uint64_t *flags, uint64_t nflags)
+unveil_setflags(int *flags, int nflags)
 {
 #if 0
        if (((~(*flags)) & nflags) != 0) {
@@ -403,7 +408,7 @@ unveil_add(struct proc *p, struct nameid
        struct unveil *uv;
        int directory_add;
        int ret = EINVAL;
-       u_int64_t flags;
+       int flags;
 
        KASSERT(ISSET(ndp->ni_cnd.cn_flags, HASBUF)); /* must have SAVENAME */
 
@@ -525,13 +530,50 @@ unveil_add(struct proc *p, struct nameid
        return ret;
 }
 
+static inline int
+unveil_pledgetopermissions(uint64_t pledge_flags)
+{
+       static const struct {
+               uint64_t pledge;
+               int      unveil;
+       } flags[] = {
+               { PLEDGE_RPATH, UNVEIL_READ },
+               { PLEDGE_WPATH, UNVEIL_WRITE },
+               { PLEDGE_EXEC,  UNVEIL_EXEC },
+               { PLEDGE_CPATH, UNVEIL_CREATE },
+               { PLEDGE_CHOWN, UNVEIL_WRITE },
+               { PLEDGE_DPATH, UNVEIL_CREATE },
+               { PLEDGE_FATTR, UNVEIL_WRITE },
+               { PLEDGE_TTY,   UNVEIL_WRITE },
+               { PLEDGE_UNIX,  UNVEIL_READ|UNVEIL_WRITE },
+               { PLEDGE_STAT,  0 },
+               { PLEDGE_STATLIE, 0 },
+               { 0, 0 },
+       };
+       int i;
+       int permissions = 0;
+
+       for (i=0; flags[i].pledge != 0; i++)
+               if (ISSET(pledge_flags, flags[i].pledge)) {
+                       SET(permissions, flags[i].unveil);
+                       CLR(pledge_flags, flags[i].pledge);
+               }
+
+       if (pledge_flags != 0)
+               panic("missing flag in pledge->unveil conversion: %llu", 
pledge_flags);
+
+       return permissions;
+}
+
 /*
  * XXX this will probably change.
  * XXX collapse down later once debug surely unneded
  */
 int
-unveil_flagmatch(struct nameidata *ni, uint64_t flags)
+unveil_flagmatch(struct nameidata *ni, int flags)
 {
+       int ni_perms = unveil_pledgetopermissions(ni->ni_pledge);
+
        if (flags == 0) {
                if (ni->ni_pledge & PLEDGE_STAT) {
 #ifdef DEBUG_UNVEIL
@@ -552,32 +594,32 @@ unveil_flagmatch(struct nameidata *ni, u
                CLR(ni->ni_pledge, PLEDGE_STATLIE);
                return 1;
        }
-       if (ni->ni_pledge & PLEDGE_RPATH) {
-               if ((flags & PLEDGE_RPATH) == 0) {
+       if (ni_perms & UNVEIL_READ) {
+               if ((flags & UNVEIL_READ) == 0) {
 #ifdef DEBUG_UNVEIL
                        printf("Pledge wants read but disallowed\n");
 #endif
                        return 0;
                }
        }
-       if (ni->ni_pledge & PLEDGE_WPATH) {
-               if ((flags & PLEDGE_WPATH) == 0) {
+       if (ni_perms & UNVEIL_WRITE) {
+               if ((flags & UNVEIL_WRITE) == 0) {
 #ifdef DEBUG_UNVEIL
                        printf("Pledge wants write but disallowed\n");
 #endif
                        return 0;
                }
        }
-       if (ni->ni_pledge & PLEDGE_EXEC) {
-               if ((flags & PLEDGE_EXEC) == 0) {
+       if (ni_perms & UNVEIL_EXEC) {
+               if ((flags & UNVEIL_EXEC) == 0) {
 #ifdef DEBUG_UNVEIL
                        printf("Pledge wants exec but disallowed\n");
 #endif
                        return 0;
                }
        }
-       if (ni->ni_pledge & PLEDGE_CPATH) {
-               if ((flags & PLEDGE_CPATH) == 0) {
+       if (ni_perms & UNVEIL_CREATE) {
+               if ((flags & UNVEIL_CREATE) == 0) {
 #ifdef DEBUG_UNVEIL
                        printf("Pledge wants cpath but disallowed\n");
 #endif

Reply via email to