FreeBSD Bugzilla – Attachment 14230 Details for
Bug 26740
[PATCH] jail improvement
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
file.diff
file.diff (text/plain), 6.07 KB, created by
Oliver Fromme
on 2001-04-21 00:20:02 UTC
(
hide
)
Description:
file.diff
Filename:
MIME Type:
Creator:
Oliver Fromme
Created:
2001-04-21 00:20:02 UTC
Size:
6.07 KB
patch
obsolete
>--- src/sys/sys/jail.h.orig Wed Nov 1 18:58:06 2000 >+++ src/sys/sys/jail.h Sat Apr 7 21:00:39 2001 >@@ -30,6 +30,17 @@ > MALLOC_DECLARE(M_PRISON); > #endif > >+ >+#ifndef MNAMELEN >+/* This is taken from sys/mount.h. */ >+#ifdef __i386__ >+#define MNAMELEN 80 /* length of buffer for returned name */ >+#endif >+#ifdef __alpha__ >+#define MNAMELEN 72 /* length of buffer for returned name */ >+#endif >+#endif >+ > /* > * This structure describes a prison. It is pointed to by all struct > * proc's of the inmates. pr_ref keeps track of them and is used to >@@ -39,6 +50,7 @@ > struct prison { > int pr_ref; > char pr_host[MAXHOSTNAMELEN]; >+ char pr_path[MNAMELEN]; > u_int32_t pr_ip; > void *pr_linux; > }; >--- src/sys/kern/kern_jail.c.orig Wed Nov 1 18:58:06 2000 >+++ src/sys/kern/kern_jail.c Sat Apr 7 21:04:31 2001 >@@ -69,6 +69,9 @@ > error = copyinstr(j.hostname, &pr->pr_host, sizeof pr->pr_host, 0); > if (error) > goto bail; >+ error = copyinstr(j.path, &pr->pr_path, sizeof pr->pr_path, 0); >+ if (error) >+ goto bail; > pr->pr_ip = j.ip_number; > > ca.path = j.path; >--- src/sys/kern/vfs_syscalls.c.orig Tue Mar 20 12:45:01 2001 >+++ src/sys/kern/vfs_syscalls.c Fri Apr 20 23:47:16 2001 >@@ -59,6 +59,7 @@ > #include <sys/unistd.h> > #include <sys/vnode.h> > #include <sys/proc.h> >+#include <sys/jail.h> > #include <sys/dirent.h> > #include <sys/extattr.h> > >@@ -72,6 +73,8 @@ > > static int change_dir __P((struct nameidata *ndp, struct proc *p)); > static void checkdirs __P((struct vnode *olddp)); >+static int check_prison_mount __P((struct proc *p, struct statfs *sp)); >+static void trim_prison_mount __P((struct statfs *sp, int pripl)); > static int chroot_refuse_vdir_fds __P((struct filedesc *fdp)); > static int getutimes __P((const struct timeval *, struct timespec *)); > static int setfown __P((struct proc *, struct vnode *, uid_t, gid_t)); >@@ -609,6 +612,62 @@ > } > > /* >+ * Check if we're imprisoned and whether the mountpoint >+ * is inside our prison. Return values: >+ * -1 if we're not supposed to see this mount. >+ * 0 if it's alright. >+ * >0 strip that many characters from the beginning of >+ * the path of the mountpoint. E.g. if the mount >+ * point is /foo/bar and the jail is chrooted at /foo, >+ * 4 is be returned, so only /bar will be left. >+ */ >+static int >+check_prison_mount(p, sp) >+ struct proc *p; >+ struct statfs *sp; >+{ >+ register char *prip; /* prison path */ >+ register int pripl; /* prison path length */ >+ >+ if (!p->p_prison) >+ return (0); >+ prip = p->p_prison->pr_path; >+ pripl = strlen(prip); >+ if (pripl > 0 && prip[pripl - 1] == '/') >+ pripl--; /* ignore trailing slash, if any */ >+ /* >+ * Note that it is not sufficient to check for the >+ * first <pripl> characters to be the same. >+ * We also have to make sure that the next character >+ * in the mountpoint path is either '\0' or '/'. >+ * Otherwise a jail in "/foo/bar" would be allowed >+ * to see a mount at "/foo/barbara". >+ */ >+ if (strncmp(prip, sp->f_mntonname, pripl) != 0 || >+ (sp->f_mntonname[pripl] != '\0' && sp->f_mntonname[pripl] != '/')) >+ return (-1); /* not our business */ >+ return (pripl); >+} >+ >+/* >+ * Remove the jail chroot path from the mountpoint, >+ * so that imprisoned users see everything relative >+ * to their jail chroot. >+ */ >+static void >+trim_prison_mount(sp, pripl) >+ struct statfs *sp; >+ int pripl; /* prison path length */ >+{ >+ strcpy(sp->f_mntonname, sp->f_mntonname + pripl); >+ /* If there's nothing left, this ought to be "/". */ >+ if (sp->f_mntonname[0] == '\0') { >+ sp->f_mntonname[0] = '/'; >+ sp->f_mntonname[1] = '\0'; >+ } >+} >+ >+/* > * Get filesystem statistics. > */ > #ifndef _SYS_SYSPROTO_H_ >@@ -629,6 +688,8 @@ > register struct mount *mp; > register struct statfs *sp; > int error; >+ int pripl; >+ int nonsu; > struct nameidata nd; > struct statfs sb; > >@@ -639,13 +700,19 @@ > sp = &mp->mnt_stat; > NDFREE(&nd, NDF_ONLY_PNBUF); > vrele(nd.ni_vp); >+ if ((pripl = check_prison_mount(p, sp)) < 0) >+ return (ENOENT); > error = VFS_STATFS(mp, sp, p); > if (error) > return (error); > sp->f_flags = mp->mnt_flag & MNT_VISFLAGMASK; >- if (suser_xxx(p->p_ucred, 0, 0)) { >+ nonsu = suser_xxx(p->p_ucred, 0, 0); >+ if (nonsu || pripl) { > bcopy((caddr_t)sp, (caddr_t)&sb, sizeof(sb)); >- sb.f_fsid.val[0] = sb.f_fsid.val[1] = 0; >+ if (nonsu) >+ sb.f_fsid.val[0] = sb.f_fsid.val[1] = 0; >+ if (pripl) >+ trim_prison_mount(&sb, pripl); > sp = &sb; > } > return (copyout((caddr_t)sp, (caddr_t)SCARG(uap, buf), sizeof(*sp))); >@@ -673,19 +740,27 @@ > struct mount *mp; > register struct statfs *sp; > int error; >+ int pripl; >+ int nonsu; > struct statfs sb; > > if ((error = getvnode(p->p_fd, SCARG(uap, fd), &fp)) != 0) > return (error); > mp = ((struct vnode *)fp->f_data)->v_mount; > sp = &mp->mnt_stat; >+ if ((pripl = check_prison_mount(p, sp)) < 0) >+ return (ENOENT); > error = VFS_STATFS(mp, sp, p); > if (error) > return (error); > sp->f_flags = mp->mnt_flag & MNT_VISFLAGMASK; >- if (suser_xxx(p->p_ucred, 0, 0)) { >+ nonsu = suser_xxx(p->p_ucred, 0, 0); >+ if (nonsu || pripl) { > bcopy((caddr_t)sp, (caddr_t)&sb, sizeof(sb)); >- sb.f_fsid.val[0] = sb.f_fsid.val[1] = 0; >+ if (nonsu) >+ sb.f_fsid.val[0] = sb.f_fsid.val[1] = 0; >+ if (pripl) >+ trim_prison_mount(&sb, pripl); > sp = &sb; > } > return (copyout((caddr_t)sp, (caddr_t)SCARG(uap, buf), sizeof(*sp))); >@@ -714,13 +789,16 @@ > register struct statfs *sp; > caddr_t sfsp; > long count, maxcount, error; >+ int pripl; >+ struct statfs sb; > > maxcount = SCARG(uap, bufsize) / sizeof(struct statfs); > sfsp = (caddr_t)SCARG(uap, buf); > count = 0; > simple_lock(&mountlist_slock); > for (mp = TAILQ_FIRST(&mountlist); mp != NULL; mp = nmp) { >- if (vfs_busy(mp, LK_NOWAIT, &mountlist_slock, p)) { >+ pripl = check_prison_mount(p, &mp->mnt_stat); >+ if (pripl < 0 || vfs_busy(mp, LK_NOWAIT, &mountlist_slock, p)) { > nmp = TAILQ_NEXT(mp, mnt_list); > continue; > } >@@ -740,6 +818,11 @@ > continue; > } > sp->f_flags = mp->mnt_flag & MNT_VISFLAGMASK; >+ if (pripl) { >+ bcopy((caddr_t)sp, (caddr_t)&sb, sizeof(sb)); >+ trim_prison_mount(&sb, pripl); >+ sp = &sb; >+ } > error = copyout((caddr_t)sp, sfsp, sizeof(*sp)); > if (error) { > vfs_unbusy(mp, p);
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 26740
: 14230