Skip to content

Commit d81b337

Browse files
Jamie GrittonJamie Gritton
authored andcommitted
jaildesc: remove file-mode-based access controls
Jail descriptors were given a file-like mode, user, and group, for the purpose of controlling how the descriptor may be used. This is too far removed from the file paradigm to make sense. Remove it in favor of a better access control method to be added, such as Capsicum. Also add missing code in jaildesc_fill_kinfo. Reported by: crest at rlwinm.de, kib MFC after: 3 days
1 parent c8fb5a4 commit d81b337

File tree

4 files changed

+36
-217
lines changed

4 files changed

+36
-217
lines changed

lib/libsys/jail.2

Lines changed: 0 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -340,31 +340,6 @@ work the same as
340340
and
341341
.Fn jail_remove ,
342342
except that they operate on the jail referred to by the passed descriptor.
343-
.Pp
344-
Jail operations via descriptors can be done by processes that do not
345-
normally have permission to see or affect the jail,
346-
as long as they are allowed by the file permissions of the jail
347-
descriptor itself.
348-
These permissions can be changed by the descriptor owner via
349-
.Xr fchmod 2
350-
and
351-
.Xr fchown 2 .
352-
.Fn jail_get
353-
requires read permission,
354-
.Fn jail_set
355-
and
356-
.Fn jail_remove
357-
require write permission,
358-
and
359-
.Fn jail_attach
360-
requires execute permission.
361-
Also, use of a descriptor with the
362-
.Dv JAIL_AT_DESC
363-
flag requires execute permission.
364-
An owning descriptor is identified by the
365-
.Em sticky bit ,
366-
which may also be changed via
367-
.Xr fchmod 2 .
368343
.Sh RETURN VALUES
369344
If successful,
370345
.Fn jail ,
@@ -402,22 +377,6 @@ The
402377
system call
403378
will fail if:
404379
.Bl -tag -width Er
405-
.It Bq Er EACCES
406-
Write permission is denied on the jail descriptor in the
407-
.Va desc
408-
parameter,
409-
and the
410-
.Dv JAIL_USE_DESC
411-
flag was set.
412-
.It Bq Er EACCES
413-
Execute permission is denied on the jail descriptor in the
414-
.Va desc
415-
parameter,
416-
and either the
417-
.Dv JAIL_AT_DESC
418-
or
419-
.Dv JAIL_ATTACH
420-
flag was set.
421380
.It Bq Er EPERM
422381
This process is not allowed to create a jail, either because it is not
423382
the super-user, or because it would exceed the jail's
@@ -505,24 +464,6 @@ The
505464
system call
506465
will fail if:
507466
.Bl -tag -width Er
508-
.It Bq Er EACCES
509-
Read permission is denied on the jail descriptor in the
510-
.Va desc
511-
parameter,
512-
and the
513-
.Dv JAIL_USE_DESC
514-
flag was set.
515-
.It Bq Er EACCES
516-
Execute permission is denied on the jail descriptor in the
517-
.Va desc
518-
parameter,
519-
and the
520-
.Dv JAIL_AT_DESC
521-
flag was set.
522-
.It Bq Er EFAULT
523-
.Fa Iov ,
524-
or one of the addresses contained within it,
525-
points to an address outside the allocated address space of the process.
526467
.It Bq Er ENOENT
527468
The jail referred to by a
528469
.Va jid
@@ -597,14 +538,6 @@ will fail if:
597538
The
598539
.Fa fd
599540
argument is not a valid jail descriptor.
600-
.It Bq Er EACCES
601-
Permission is denied on the jail descriptor
602-
.Po
603-
execute permission for
604-
.Fn jail_attach_fd ,
605-
or write permission for
606-
.Fn jail_remove_fd
607-
.Pc .
608541
.It Bq Er EPERM
609542
The jail descriptor was created by a user other than the super-user.
610543
.It Bq Er EINVAL

sys/kern/kern_jail.c

Lines changed: 9 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -991,7 +991,6 @@ int
991991
kern_jail_set(struct thread *td, struct uio *optuio, int flags)
992992
{
993993
struct file *jfp_out;
994-
struct jaildesc *desc_in;
995994
struct nameidata nd;
996995
#ifdef INET
997996
struct prison_ip *ip4;
@@ -1095,24 +1094,13 @@ kern_jail_set(struct thread *td, struct uio *optuio, int flags)
10951094
* descriptor's prison.
10961095
*/
10971096
prison_free(mypr);
1098-
error = jaildesc_find(td, jfd_in, &desc_in, &mypr,
1099-
NULL);
1097+
error = jaildesc_find(td, jfd_in, &mypr, NULL);
11001098
if (error != 0) {
11011099
vfs_opterror(opts, error == ENOENT ?
11021100
"descriptor to dead jail" :
11031101
"not a jail descriptor");
11041102
goto done_errmsg;
11051103
}
1106-
/*
1107-
* Check file permissions using the current
1108-
* credentials, and operation permissions
1109-
* using the descriptor's credentials.
1110-
*/
1111-
error = vaccess(VREG, desc_in->jd_mode, desc_in->jd_uid,
1112-
desc_in->jd_gid, VEXEC, td->td_ucred);
1113-
JAILDESC_UNLOCK(desc_in);
1114-
if (error != 0)
1115-
goto done_free;
11161104
if ((flags & JAIL_CREATE) && mypr->pr_childmax == 0) {
11171105
error = EPERM;
11181106
goto done_free;
@@ -1516,27 +1504,15 @@ kern_jail_set(struct thread *td, struct uio *optuio, int flags)
15161504
}
15171505
if (flags & JAIL_USE_DESC) {
15181506
/* Get the jail from its descriptor. */
1519-
error = jaildesc_find(td, jfd_in, &desc_in, &pr, &jdcred);
1507+
error = jaildesc_find(td, jfd_in, &pr, &jdcred);
15201508
if (error) {
15211509
vfs_opterror(opts, error == ENOENT ?
15221510
"descriptor to dead jail" :
15231511
"not a jail descriptor");
15241512
goto done_deref;
15251513
}
15261514
drflags |= PD_DEREF;
1527-
/*
1528-
* Check file permissions using the current credentials,
1529-
* and operation permissions using the descriptor's
1530-
* credentials.
1531-
*/
1532-
error = vaccess(VREG, desc_in->jd_mode, desc_in->jd_uid,
1533-
desc_in->jd_gid, VWRITE, td->td_ucred);
1534-
if (error == 0 && (flags & JAIL_ATTACH))
1535-
error = vaccess(VREG, desc_in->jd_mode, desc_in->jd_uid,
1536-
desc_in->jd_gid, VEXEC, td->td_ucred);
1537-
JAILDESC_UNLOCK(desc_in);
1538-
if (error == 0)
1539-
error = priv_check_cred(jdcred, PRIV_JAIL_SET);
1515+
error = priv_check_cred(jdcred, PRIV_JAIL_SET);
15401516
if (error == 0 && (flags & JAIL_ATTACH))
15411517
error = priv_check_cred(jdcred, PRIV_JAIL_ATTACH);
15421518
crfree(jdcred);
@@ -2500,7 +2476,6 @@ kern_jail_get(struct thread *td, struct uio *optuio, int flags)
25002476
{
25012477
struct bool_flags *bf;
25022478
struct file *jfp_out;
2503-
struct jaildesc *desc_in;
25042479
struct jailsys_flags *jsf;
25052480
struct prison *pr, *mypr;
25062481
struct vfsopt *opt;
@@ -2547,19 +2522,14 @@ kern_jail_get(struct thread *td, struct uio *optuio, int flags)
25472522
}
25482523
if (flags & JAIL_USE_DESC) {
25492524
/* Get the jail from its descriptor. */
2550-
error = jaildesc_find(td, jfd_in, &desc_in, &pr, NULL);
2525+
error = jaildesc_find(td, jfd_in, &pr, NULL);
25512526
if (error) {
25522527
vfs_opterror(opts, error == ENOENT ?
25532528
"descriptor to dead jail" :
25542529
"not a jail descriptor");
25552530
goto done;
25562531
}
25572532
drflags |= PD_DEREF;
2558-
error = vaccess(VREG, desc_in->jd_mode, desc_in->jd_uid,
2559-
desc_in->jd_gid, VREAD, td->td_ucred);
2560-
JAILDESC_UNLOCK(desc_in);
2561-
if (error != 0)
2562-
goto done;
25632533
mtx_lock(&pr->pr_mtx);
25642534
drflags |= PD_LOCKED;
25652535
if (!(prison_isalive(pr) || (flags & JAIL_DYING))) {
@@ -2573,19 +2543,13 @@ kern_jail_get(struct thread *td, struct uio *optuio, int flags)
25732543
if (flags & JAIL_AT_DESC) {
25742544
/* Look up jails based on the descriptor's prison. */
25752545
prison_free(mypr);
2576-
error = jaildesc_find(td, jfd_in, &desc_in, &mypr,
2577-
NULL);
2546+
error = jaildesc_find(td, jfd_in, &mypr, NULL);
25782547
if (error != 0) {
25792548
vfs_opterror(opts, error == ENOENT ?
25802549
"descriptor to dead jail" :
25812550
"not a jail descriptor");
25822551
goto done;
25832552
}
2584-
error = vaccess(VREG, desc_in->jd_mode, desc_in->jd_uid,
2585-
desc_in->jd_gid, VEXEC, td->td_ucred);
2586-
JAILDESC_UNLOCK(desc_in);
2587-
if (error != 0)
2588-
goto done;
25892553
}
25902554
if (flags & (JAIL_GET_DESC | JAIL_OWN_DESC)) {
25912555
/* Allocate a jail descriptor to return later. */
@@ -2916,23 +2880,14 @@ sys_jail_remove(struct thread *td, struct jail_remove_args *uap)
29162880
int
29172881
sys_jail_remove_jd(struct thread *td, struct jail_remove_jd_args *uap)
29182882
{
2919-
struct jaildesc *jd;
29202883
struct prison *pr;
29212884
struct ucred *jdcred;
29222885
int error;
29232886

2924-
error = jaildesc_find(td, uap->fd, &jd, &pr, &jdcred);
2887+
error = jaildesc_find(td, uap->fd, &pr, &jdcred);
29252888
if (error)
29262889
return (error);
2927-
/*
2928-
* Check file permissions using the current credentials, and
2929-
* operation permissions using the descriptor's credentials.
2930-
*/
2931-
error = vaccess(VREG, jd->jd_mode, jd->jd_uid, jd->jd_gid, VWRITE,
2932-
td->td_ucred);
2933-
JAILDESC_UNLOCK(jd);
2934-
if (error == 0)
2935-
error = priv_check_cred(jdcred, PRIV_JAIL_REMOVE);
2890+
error = priv_check_cred(jdcred, PRIV_JAIL_REMOVE);
29362891
crfree(jdcred);
29372892
if (error) {
29382893
prison_free(pr);
@@ -3002,26 +2957,17 @@ sys_jail_attach(struct thread *td, struct jail_attach_args *uap)
30022957
int
30032958
sys_jail_attach_jd(struct thread *td, struct jail_attach_jd_args *uap)
30042959
{
3005-
struct jaildesc *jd;
30062960
struct prison *pr;
30072961
struct ucred *jdcred;
30082962
int drflags, error;
30092963

30102964
sx_slock(&allprison_lock);
30112965
drflags = PD_LIST_SLOCKED;
3012-
error = jaildesc_find(td, uap->fd, &jd, &pr, &jdcred);
2966+
error = jaildesc_find(td, uap->fd, &pr, &jdcred);
30132967
if (error)
30142968
goto fail;
30152969
drflags |= PD_DEREF;
3016-
/*
3017-
* Check file permissions using the current credentials, and
3018-
* operation permissions using the descriptor's credentials.
3019-
*/
3020-
error = vaccess(VREG, jd->jd_mode, jd->jd_uid, jd->jd_gid, VEXEC,
3021-
td->td_ucred);
3022-
JAILDESC_UNLOCK(jd);
3023-
if (error == 0)
3024-
error = priv_check_cred(jdcred, PRIV_JAIL_ATTACH);
2970+
error = priv_check_cred(jdcred, PRIV_JAIL_ATTACH);
30252971
crfree(jdcred);
30262972
if (error)
30272973
goto fail;

0 commit comments

Comments
 (0)