On Sat, Jan 08, 2022 at 12:41:53PM +0100, Claudio Jeker wrote: > > Ah no, that was some other flag for something else :) > Anyway I decided to make UNVEIL_USERSET a real flag and set it whenever a > node has flags set by the user. This way it is possible to check if a node > was added implicit or explict. > > Now to not alter the result of EACCES vs ENOENT one also needs to check if > any of the other flags was set or not. Because of this I added UNVEIL_MASK > and made sure that all return cases where that matters make this > distinction. > > This diff seems to fix both of your test cases and also passes regress.
and it makes the code more easily understandable. ok semarie@ > -- > :wq Claudio > > Index: kern/kern_unveil.c > =================================================================== > RCS file: /cvs/src/sys/kern/kern_unveil.c,v > retrieving revision 1.51 > diff -u -p -r1.51 kern_unveil.c > --- kern/kern_unveil.c 9 Sep 2021 13:02:36 -0000 1.51 > +++ kern/kern_unveil.c 8 Jan 2022 11:26:01 -0000 > @@ -345,7 +345,7 @@ unveil_parsepermissions(const char *perm > size_t i = 0; > char c; > > - *perms = 0; > + *perms = UNVEIL_USERSET; > while ((c = permissions[i++]) != '\0') { > switch (c) { > case 'r': > @@ -708,11 +708,13 @@ unveil_check_final(struct proc *p, struc > if (ni->ni_vp != NULL && ni->ni_vp->v_type == VDIR) { > /* We are matching a directory terminal component */ > uv = unveil_lookup(ni->ni_vp, pr, NULL); > - if (uv == NULL) { > + if (uv == NULL || (uv->uv_flags & UNVEIL_USERSET) == 0) { > #ifdef DEBUG_UNVEIL > printf("unveil: %s(%d) no match for vnode %p\n", > pr->ps_comm, pr->ps_pid, ni->ni_vp); > #endif > + if (uv != NULL) > + ni->ni_unveil_match = uv; > goto done; > } > if (!unveil_flagmatch(ni, uv->uv_flags)) { > @@ -722,7 +724,7 @@ unveil_check_final(struct proc *p, struc > pr->ps_comm, pr->ps_pid, ni->ni_vp); > #endif > pr->ps_acflag |= AUNVEIL; > - if (uv->uv_flags & UNVEIL_USERSET) > + if (uv->uv_flags & UNVEIL_MASK) > return EACCES; > else > return ENOENT; > @@ -764,12 +766,15 @@ unveil_check_final(struct proc *p, struc > #endif > /* > * If dir has user set restrictions fail with > - * EACCES. Otherwise, use any covering match > - * that we found above this dir. > + * EACCES or ENOENT. Otherwise, use any covering > + * match that we found above this dir. > */ > if (uv->uv_flags & UNVEIL_USERSET) { > pr->ps_acflag |= AUNVEIL; > - return EACCES; > + if (uv->uv_flags & UNVEIL_MASK) > + return EACCES; > + else > + return ENOENT; > } > /* start backtrack from this node */ > ni->ni_unveil_match = uv; > @@ -820,7 +825,10 @@ done: > pr->ps_comm, pr->ps_pid, uv->uv_vp); > #endif > pr->ps_acflag |= AUNVEIL; > - return EACCES; > + if (uv->uv_flags & UNVEIL_MASK) > + return EACCES; > + else > + return ENOENT; > } > #ifdef DEBUG_UNVEIL > printf("unveil: %s(%d) check cover for vnode %p, uv_cover > %zd\n", > Index: sys/namei.h > =================================================================== > RCS file: /cvs/src/sys/sys/namei.h,v > retrieving revision 1.48 > diff -u -p -r1.48 namei.h > --- sys/namei.h 2 Sep 2021 12:35:23 -0000 1.48 > +++ sys/namei.h 8 Jan 2022 11:32:39 -0000 > @@ -268,6 +268,7 @@ struct nchstats { > #define UNVEIL_WRITE 0x02 > #define UNVEIL_CREATE 0x04 > #define UNVEIL_EXEC 0x08 > -#define UNVEIL_USERSET 0x0F > +#define UNVEIL_USERSET 0x10 > +#define UNVEIL_MASK 0x0F > > #endif /* !_SYS_NAMEI_H_ */ -- Sebastien Marie