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