Skip to content

Commit

Permalink
Fix unveil issue noticed by kn@ where unveil does not notice covering
Browse files Browse the repository at this point in the history
unveil matches when .. is used correctly.  Also adds regress based
upon his test program for the same issue.
  • Loading branch information
bob-beck committed Jan 14, 2019
1 parent c319aed commit 6fd26cb
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 5 deletions.
20 changes: 19 additions & 1 deletion regress/sys/kern/unveil/syscalls.c
@@ -1,4 +1,4 @@
/* $OpenBSD: syscalls.c,v 1.18 2018/10/28 22:42:33 beck Exp $ */
/* $OpenBSD: syscalls.c,v 1.19 2019/01/14 04:02:39 beck Exp $ */

/*
* Copyright (c) 2017-2018 Bob Beck <beck@openbsd.org>
Expand Down Expand Up @@ -835,6 +835,23 @@ test_dotdotup(int do_uv)
return 0;
}

static int
test_kn(int do_uv)
{
if (do_uv) {
printf("testing read only with one writeable file\n");
if (unveil("/", "r") == -1)
err(1, "%s:%d - unveil", __FILE__, __LINE__);
if (unveil("/dev/null", "rw") == -1)
err(1, "%s:%d - unveil", __FILE__, __LINE__);
}
UV_SHOULD_SUCCEED((open("/dev/null", O_RDWR) == -1), "open");
UV_SHOULD_SUCCEED((open("/dev/zero", O_RDONLY) == -1), "open");
UV_SHOULD_ENOENT((open("/dev/zero", O_RDWR) == -1), "open"); /* XXX */
return 0;
}


int
main (int argc, char *argv[])
{
Expand Down Expand Up @@ -880,5 +897,6 @@ main (int argc, char *argv[])
failures += runcompare(test_bypassunveil);
failures += runcompare_internal(test_fork, 0);
failures += runcompare(test_dotdotup);
failures += runcompare(test_kn);
exit(failures);
}
11 changes: 7 additions & 4 deletions sys/kern/kern_unveil.c
@@ -1,4 +1,4 @@
/* $OpenBSD: kern_unveil.c,v 1.19 2019/01/06 18:33:26 kettenis Exp $ */
/* $OpenBSD: kern_unveil.c,v 1.20 2019/01/14 04:02:39 beck Exp $ */

/*
* Copyright (c) 2017-2018 Bob Beck <beck@openbsd.org>
Expand Down Expand Up @@ -740,8 +740,11 @@ unveil_check_component(struct proc *p, struct nameidata *ni, struct vnode *dp)
/*
* adjust unveil match as necessary
*/
ni->ni_unveil_match = unveil_covered(
ni->ni_unveil_match, dp, p->p_p);
uv = unveil_covered(ni->ni_unveil_match, dp,
p->p_p);
/* clear the match when we DOTDOT above it */
if (ni->ni_unveil_match->uv_vp == dp)
ni->ni_unveil_match = NULL;
}
else
uv = unveil_lookup(dp, p, NULL);
Expand Down Expand Up @@ -843,7 +846,7 @@ unveil_check_final(struct proc *p, struct nameidata *ni)
if (uv->uv_flags & UNVEIL_USERSET)
return EACCES;
else
return ENOENT;
goto done;
}
/* directory flags match, update match */
if (uv->uv_flags & UNVEIL_USERSET)
Expand Down

0 comments on commit 6fd26cb

Please sign in to comment.