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