Page MenuHomeFreeBSD

D44373.id54425.diff
No OneTemporary

D44373.id54425.diff

diff --git a/include/unistd.h b/include/unistd.h
--- a/include/unistd.h
+++ b/include/unistd.h
@@ -465,6 +465,7 @@
#if (__XSI_VISIBLE && __XSI_VISIBLE <= 500) || __BSD_VISIBLE
int brk(const void *);
int chroot(const char *);
+int fchroot(int);
int getdtablesize(void);
int getpagesize(void) __pure2;
char *getpass(const char *);
diff --git a/lib/libsys/Makefile.sys b/lib/libsys/Makefile.sys
--- a/lib/libsys/Makefile.sys
+++ b/lib/libsys/Makefile.sys
@@ -417,6 +417,7 @@
MLINKS+=chown.2 fchown.2 \
chown.2 fchownat.2 \
chown.2 lchown.2
+MLINKS+=chroot.2 fchroot.2
MLINKS+=clock_gettime.2 clock_getres.2 \
clock_gettime.2 clock_settime.2
MLINKS+=closefrom.2 close_range.2
diff --git a/lib/libsys/Symbol.sys.map b/lib/libsys/Symbol.sys.map
--- a/lib/libsys/Symbol.sys.map
+++ b/lib/libsys/Symbol.sys.map
@@ -429,6 +429,7 @@
FBSD_1.8 {
kcmp;
+ fchroot;
};
FBSDprivate_1.0 {
diff --git a/lib/libsys/chroot.2 b/lib/libsys/chroot.2
--- a/lib/libsys/chroot.2
+++ b/lib/libsys/chroot.2
@@ -29,7 +29,8 @@
.Dt CHROOT 2
.Os
.Sh NAME
-.Nm chroot
+.Nm chroot ,
+.Nm fchroot
.Nd change root directory
.Sh LIBRARY
.Lb libc
@@ -37,6 +38,8 @@
.In unistd.h
.Ft int
.Fn chroot "const char *dirname"
+.Ft int
+.Fn fchroot "int fd"
.Sh DESCRIPTION
The
.Fa dirname
@@ -92,6 +95,12 @@
mimicking the historic insecure behavior of
.Fn chroot
still present on other systems.
+.Pp
+The
+.Fn fchroot
+is identical to
+.Fn chroot
+except it takes a file descriptor instead of path.
.Sh RETURN VALUES
.Rv -std
.Sh ERRORS
diff --git a/lib/libsys/syscalls.map b/lib/libsys/syscalls.map
--- a/lib/libsys/syscalls.map
+++ b/lib/libsys/syscalls.map
@@ -801,4 +801,6 @@
__sys_timerfd_settime;
_kcmp;
__sys_kcmp;
+ _fchroot;
+ __sys_fchroot;
};
diff --git a/share/man/man4/rights.4 b/share/man/man4/rights.4
--- a/share/man/man4/rights.4
+++ b/share/man/man4/rights.4
@@ -164,9 +164,6 @@
.It Dv CAP_EXTATTR_SET
Permit
.Xr extattr_set_fd 2 .
-.It Dv CAP_FCHDIR
-Permit
-.Xr fchdir 2 .
.It Dv CAP_FCHFLAGS
Permit
.Xr fchflags 2
diff --git a/sys/kern/imgact_elf.c b/sys/kern/imgact_elf.c
--- a/sys/kern/imgact_elf.c
+++ b/sys/kern/imgact_elf.c
@@ -792,15 +792,6 @@
u_long base_addr = 0;
int error;
-#ifdef CAPABILITY_MODE
- /*
- * XXXJA: This check can go away once we are sufficiently confident
- * that the checks in namei() are correct.
- */
- if (IN_CAPABILITY_MODE(curthread))
- return (ECAPMODE);
-#endif
-
tempdata = malloc(sizeof(*tempdata), M_TEMP, M_WAITOK | M_ZERO);
nd = &tempdata->nd;
attr = &tempdata->attr;
diff --git a/sys/kern/kern_exec.c b/sys/kern/kern_exec.c
--- a/sys/kern/kern_exec.c
+++ b/sys/kern/kern_exec.c
@@ -453,18 +453,6 @@
interpret:
if (args->fname != NULL) {
-#ifdef CAPABILITY_MODE
- /*
- * While capability mode can't reach this point via direct
- * path arguments to execve(), we also don't allow
- * interpreters to be used in capability mode (for now).
- * Catch indirect lookups and return a permissions error.
- */
- if (IN_CAPABILITY_MODE(td)) {
- error = ECAPMODE;
- goto exec_fail;
- }
-#endif
/*
* Translate the file name. namei() returns a vnode
diff --git a/sys/kern/kern_mib.c b/sys/kern/kern_mib.c
--- a/sys/kern/kern_mib.c
+++ b/sys/kern/kern_mib.c
@@ -98,7 +98,7 @@
SYSCTL_INT(_kern, KERN_OSREV, osrevision, CTLFLAG_RD | CTLFLAG_CAPRD,
SYSCTL_NULL_INT_PTR, BSD, "Operating system revision");
-SYSCTL_STRING(_kern, KERN_VERSION, version, CTLFLAG_RD,
+SYSCTL_STRING(_kern, KERN_VERSION, version, CTLFLAG_RD | CTLFLAG_CAPRD,
version, 0, "Kernel version");
SYSCTL_STRING(_kern, OID_AUTO, compiler_version, CTLFLAG_RD,
diff --git a/sys/kern/subr_capability.c b/sys/kern/subr_capability.c
--- a/sys/kern/subr_capability.c
+++ b/sys/kern/subr_capability.c
@@ -55,7 +55,6 @@
__read_mostly cap_rights_t cap_chflags_rights;
__read_mostly cap_rights_t cap_connect_rights;
__read_mostly cap_rights_t cap_event_rights;
-__read_mostly cap_rights_t cap_fchdir_rights;
__read_mostly cap_rights_t cap_fchflags_rights;
__read_mostly cap_rights_t cap_fchmod_rights;
__read_mostly cap_rights_t cap_fchown_rights;
@@ -96,6 +95,7 @@
__read_mostly cap_rights_t cap_unlinkat_rights;
__read_mostly cap_rights_t cap_write_rights;
__read_mostly cap_rights_t cap_no_rights;
+__read_mostly cap_rights_t cap_all_rights;
static void
cap_rights_sysinit(void *arg)
@@ -104,7 +104,6 @@
cap_rights_init_one(&cap_bind_rights, CAP_BIND);
cap_rights_init_one(&cap_connect_rights, CAP_CONNECT);
cap_rights_init_one(&cap_event_rights, CAP_EVENT);
- cap_rights_init_one(&cap_fchdir_rights, CAP_FCHDIR);
cap_rights_init_one(&cap_fchflags_rights, CAP_FCHFLAGS);
cap_rights_init_one(&cap_fchmod_rights, CAP_FCHMOD);
cap_rights_init_one(&cap_fchown_rights, CAP_FCHOWN);
@@ -145,6 +144,8 @@
cap_rights_init_one(&cap_unlinkat_rights, CAP_UNLINKAT);
cap_rights_init_one(&cap_write_rights, CAP_WRITE);
cap_rights_init(&cap_no_rights);
+ cap_rights_init(&cap_all_rights);
+ CAP_ALL(&cap_all_rights);
}
SYSINIT(cap_rights_sysinit, SI_SUB_COPYRIGHT, SI_ORDER_ANY, cap_rights_sysinit,
NULL);
diff --git a/sys/kern/sys_capability.c b/sys/kern/sys_capability.c
--- a/sys/kern/sys_capability.c
+++ b/sys/kern/sys_capability.c
@@ -76,6 +76,7 @@
#include <sys/systm.h>
#include <sys/ucred.h>
#include <sys/uio.h>
+#include <sys/vnode.h>
#include <sys/ktrace.h>
#include <security/audit/audit.h>
@@ -101,6 +102,15 @@
{
struct ucred *newcred, *oldcred;
struct proc *p;
+ struct vnode *ecapmodevp;
+
+ // XXX: ecapmodevp should be global
+ // XXX: ecapmode_vnodeops, to return the right errno? make sure we're returning the wrong one now.
+ getnewvnode("ecapmode", NULL, &dead_vnodeops, &ecapmodevp);
+ ecapmodevp->v_state = VSTATE_CONSTRUCTED; // XXX: needed?
+
+ pwd_chdir(td, ecapmodevp);
+ pwd_chroot(td, ecapmodevp);
if (IN_CAPABILITY_MODE(td))
return (0);
diff --git a/sys/kern/syscalls.master b/sys/kern/syscalls.master
--- a/sys/kern/syscalls.master
+++ b/sys/kern/syscalls.master
@@ -143,7 +143,7 @@
size_t nbyte
);
}
-5 AUE_OPEN_RWTC STD {
+5 AUE_OPEN_RWTC STD|CAPENABLED {
int open(
_In_z_ const char *path,
int flags,
@@ -157,7 +157,7 @@
int fd
);
}
-7 AUE_WAIT4 STD {
+7 AUE_WAIT4 STD|CAPENABLED {
int wait4(
int pid,
_Out_opt_ int *status,
@@ -177,18 +177,18 @@
_In_z_ const char *link
);
}
-10 AUE_UNLINK STD {
+10 AUE_UNLINK STD|CAPENABLED {
int unlink(
_In_z_ const char *path
);
}
11 AUE_NULL OBSOL execv
-12 AUE_CHDIR STD {
+12 AUE_CHDIR STD|CAPENABLED {
int chdir(
_In_z_ const char *path
);
}
-13 AUE_FCHDIR STD {
+13 AUE_FCHDIR STD|CAPENABLED {
int fchdir(
int fd
);
@@ -200,7 +200,7 @@
uint32_t dev
);
}
-15 AUE_CHMOD STD {
+15 AUE_CHMOD STD|CAPENABLED {
int chmod(
_In_z_ const char *path,
mode_t mode
@@ -313,7 +313,7 @@
_Inout_ __socklen_t *alen
);
}
-33 AUE_ACCESS STD {
+33 AUE_ACCESS STD|CAPENABLED {
int access(
_In_z_ const char *path,
int amode
@@ -443,20 +443,20 @@
_In_z_ const char *path
);
}
-57 AUE_SYMLINK STD {
+57 AUE_SYMLINK STD|CAPENABLED {
int symlink(
_In_z_ const char *path,
_In_z_ const char *link
);
}
-58 AUE_READLINK STD {
+58 AUE_READLINK STD|CAPENABLED {
ssize_t readlink(
_In_z_ const char *path,
_Out_writes_z_(count) char *buf,
size_t count
);
}
-59 AUE_EXECVE STD {
+59 AUE_EXECVE STD|CAPENABLED {
int execve(
_In_z_ const char *fname,
_In_z_ char **argv,
@@ -497,7 +497,7 @@
int flags
);
}
-66 AUE_VFORK STD {
+66 AUE_VFORK STD|CAPENABLED {
int vfork(void);
}
67 AUE_NULL OBSOL vread
@@ -650,7 +650,7 @@
int protocol
);
}
-98 AUE_CONNECT STD {
+98 AUE_CONNECT STD|CAPENABLED {
int connect(
int s,
_In_reads_bytes_(namelen) const struct sockaddr *name,
@@ -836,7 +836,7 @@
int egid
);
}
-128 AUE_RENAME STD {
+128 AUE_RENAME STD|CAPENABLED {
int rename(
_In_z_ const char *from,
_In_z_ const char *to
@@ -890,7 +890,7 @@
_Out_writes_(2) int *rsv
);
}
-136 AUE_MKDIR STD {
+136 AUE_MKDIR STD|CAPENABLED {
int mkdir(
_In_z_ const char *path,
mode_t mode
@@ -1146,7 +1146,7 @@
_Out_ _Contains_timet_ struct freebsd11_stat *ub
);
}
-191 AUE_PATHCONF STD {
+191 AUE_PATHCONF STD|CAPENABLED {
int pathconf(
_In_z_ const char *path,
int name
@@ -1455,7 +1455,7 @@
int inherit
);
}
-251 AUE_RFORK STD {
+251 AUE_RFORK STD|CAPENABLED {
int rfork(
int flags
);
@@ -1692,7 +1692,7 @@
325 AUE_MUNLOCKALL STD|CAPENABLED {
int munlockall(void);
}
-326 AUE_GETCWD STD {
+326 AUE_GETCWD STD|CAPENABLED {
int __getcwd(
_Out_writes_z_(buflen) char *buf,
size_t buflen
@@ -1980,7 +1980,7 @@
);
}
375 AUE_NULL OBSOL nfsclnt
-376 AUE_EACCESS STD {
+376 AUE_EACCESS STD|CAPENABLED {
int eaccess(
_In_z_ const char *path,
int amode
@@ -2243,7 +2243,7 @@
_In_z_ const char *name
);
}
-425 AUE_ACL_GET_LINK STD {
+425 AUE_ACL_GET_LINK STD|CAPENABLED {
int __acl_get_link(
_In_z_ const char *path,
acl_type_t type,
@@ -2819,7 +2819,7 @@
_Inout_opt_ _Contains_long_ struct shmid_ds *buf
);
}
-513 AUE_LPATHCONF STD {
+513 AUE_LPATHCONF STD|CAPENABLED {
int lpathconf(
_In_z_ const char *path,
int name
@@ -3234,7 +3234,7 @@
_Inout_opt_ uint32_t *ptr
);
}
-574 AUE_REALPATHAT STD {
+574 AUE_REALPATHAT STD|CAPENABLED {
int __realpathat(
int fd,
_In_z_ const char *path,
@@ -3333,5 +3333,11 @@
uintptr_t idx2
);
}
+589 AUE_NULL STD|CAPENABLED {
+ int fchroot(
+ int fd
+ );
+ }
+
; vim: syntax=off
diff --git a/sys/kern/uipc_syscalls.c b/sys/kern/uipc_syscalls.c
--- a/sys/kern/uipc_syscalls.c
+++ b/sys/kern/uipc_syscalls.c
@@ -467,11 +467,6 @@
struct file *fp;
int error;
-#ifdef CAPABILITY_MODE
- if (IN_CAPABILITY_MODE(td) && (dirfd == AT_FDCWD))
- return (ECAPMODE);
-#endif
-
AUDIT_ARG_FD(fd);
AUDIT_ARG_SOCKADDR(td, dirfd, sa);
error = getsock(td, fd, &cap_connect_rights, &fp);
diff --git a/sys/kern/vfs_lookup.c b/sys/kern/vfs_lookup.c
--- a/sys/kern/vfs_lookup.c
+++ b/sys/kern/vfs_lookup.c
@@ -271,13 +271,6 @@
struct componentname *cnp;
cnp = &ndp->ni_cnd;
- if ((ndp->ni_lcf & NI_LCF_STRICTRELATIVE) != 0) {
-#ifdef KTRACE
- if (KTRPOINT(curthread, KTR_CAPFAIL))
- ktrcapfail(CAPFAIL_LOOKUP, NULL, NULL);
-#endif
- return (ENOTCAPABLE);
- }
while (*(cnp->cn_nameptr) == '/') {
cnp->cn_nameptr++;
ndp->ni_pathlen--;
@@ -318,15 +311,9 @@
* the relative root.
*/
if (IN_CAPABILITY_MODE(td) && (cnp->cn_flags & NOCAPCHECK) == 0) {
+ // XXX: also set NI_LCF_CAP_DOTDOT?
ndp->ni_lcf |= NI_LCF_STRICTRELATIVE;
ndp->ni_resflags |= NIRES_STRICTREL;
- if (ndp->ni_dirfd == AT_FDCWD) {
-#ifdef KTRACE
- if (KTRPOINT(td, KTR_CAPFAIL))
- ktrcapfail(CAPFAIL_LOOKUP, NULL, NULL);
-#endif
- return (ECAPMODE);
- }
}
#endif
error = 0;
@@ -344,6 +331,7 @@
if (cnp->cn_pnbuf[0] == '/') {
ndp->ni_resflags |= NIRES_ABS;
+ CAP_ALL(&ndp->ni_filecaps.fc_rights);
error = namei_handle_root(ndp, dpp);
} else {
if (ndp->ni_startdir != NULL) {
@@ -351,6 +339,7 @@
startdir_used = true;
} else if (ndp->ni_dirfd == AT_FDCWD) {
*dpp = pwd->pwd_cdir;
+ CAP_ALL(&ndp->ni_filecaps.fc_rights);
vrefact(*dpp);
} else {
if (cnp->cn_flags & AUDITVNODE1)
diff --git a/sys/kern/vfs_syscalls.c b/sys/kern/vfs_syscalls.c
--- a/sys/kern/vfs_syscalls.c
+++ b/sys/kern/vfs_syscalls.c
@@ -898,7 +898,12 @@
int error;
AUDIT_ARG_FD(uap->fd);
- error = getvnode_path(td, uap->fd, &cap_fchdir_rights,
+ /*
+ * XXX: Instead of cap_fchdir_rights we require file descriptors
+ * passed to fchdir(2) to have full rights, so then we don't
+ * need to track those rights for process' cwd and root.
+ */
+ error = getvnode_path(td, uap->fd, &cap_all_rights,
&fp);
if (error != 0)
return (error);
@@ -967,18 +972,13 @@
SYSCTL_INT(_security_bsd, OID_AUTO, unprivileged_chroot, CTLFLAG_RW,
&unprivileged_chroot, 0,
"Unprivileged processes can use chroot(2)");
+
/*
- * Change notion of root (``/'') directory.
+ * Takes locked vnode, unlocks it before returning.
*/
-#ifndef _SYS_SYSPROTO_H_
-struct chroot_args {
- char *path;
-};
-#endif
-int
-sys_chroot(struct thread *td, struct chroot_args *uap)
+static int
+kern_chroot(struct thread *td, struct vnode *vp)
{
- struct nameidata nd;
struct proc *p;
int error;
@@ -989,30 +989,80 @@
if (unprivileged_chroot == 0 ||
(p->p_flag2 & P2_NO_NEW_PRIVS) == 0) {
PROC_UNLOCK(p);
- return (error);
+ goto e_vunlock;
}
PROC_UNLOCK(p);
}
- NDINIT(&nd, LOOKUP, FOLLOW | LOCKSHARED | LOCKLEAF | AUDITVNODE1,
- UIO_USERSPACE, uap->path);
- error = namei(&nd);
- if (error != 0)
- return (error);
- NDFREE_PNBUF(&nd);
- error = change_dir(nd.ni_vp, td);
+
+ error = change_dir(vp, td);
if (error != 0)
goto e_vunlock;
#ifdef MAC
- error = mac_vnode_check_chroot(td->td_ucred, nd.ni_vp);
+ error = mac_vnode_check_chroot(td->td_ucred, vp);
if (error != 0)
goto e_vunlock;
#endif
- VOP_UNLOCK(nd.ni_vp);
- error = pwd_chroot(td, nd.ni_vp);
- vrele(nd.ni_vp);
+ VOP_UNLOCK(vp);
+ error = pwd_chroot(td, vp);
+ vrele(vp);
return (error);
e_vunlock:
- vput(nd.ni_vp);
+ vput(vp);
+ return (error);
+}
+
+/*
+ * Change notion of root (``/'') directory.
+ */
+#ifndef _SYS_SYSPROTO_H_
+struct chroot_args {
+ char *path;
+};
+#endif
+int
+sys_chroot(struct thread *td, struct chroot_args *uap)
+{
+ struct nameidata nd;
+ int error;
+
+ NDINIT(&nd, LOOKUP, FOLLOW | LOCKSHARED | LOCKLEAF | AUDITVNODE1,
+ UIO_USERSPACE, uap->path);
+ error = namei(&nd);
+ if (error != 0)
+ return (error);
+ NDFREE_PNBUF(&nd);
+ error = kern_chroot(td, nd.ni_vp);
+ return (error);
+}
+
+#ifndef _SYS_SYSPROTO_H_
+struct fchroot_args {
+ int fd;
+};
+#endif
+int
+sys_fchroot(struct thread *td, struct fchroot_args *uap)
+{
+ struct vnode *vp;
+ struct file *fp;
+ int error;
+
+ /*
+ * XXX: I don't understand how it'd interact with pwd_jdir
+ * in cache_fplookup() and namei_setup(); let's make sure
+ * it cannot happen for now.
+ */
+ if (jailed(td->td_ucred))
+ return (EPERM);
+
+ error = getvnode_path(td, uap->fd, &cap_all_rights, &fp);
+ if (error != 0)
+ return (error);
+ vp = fp->f_vnode;
+ vrefact(vp);
+ fdrop(fp, td);
+ vn_lock(vp, LK_SHARED | LK_RETRY);
+ error = kern_chroot(td, vp);
return (error);
}
diff --git a/sys/sys/caprights.h b/sys/sys/caprights.h
--- a/sys/sys/caprights.h
+++ b/sys/sys/caprights.h
@@ -59,10 +59,10 @@
#ifdef _KERNEL
extern cap_rights_t cap_accept_rights;
+extern cap_rights_t cap_all_rights;
extern cap_rights_t cap_bind_rights;
extern cap_rights_t cap_connect_rights;
extern cap_rights_t cap_event_rights;
-extern cap_rights_t cap_fchdir_rights;
extern cap_rights_t cap_fchflags_rights;
extern cap_rights_t cap_fchmod_rights;
extern cap_rights_t cap_fchown_rights;
diff --git a/sys/sys/capsicum.h b/sys/sys/capsicum.h
--- a/sys/sys/capsicum.h
+++ b/sys/sys/capsicum.h
@@ -114,7 +114,7 @@
#define CAP_LOOKUP CAPRIGHT(0, 0x0000000000000400ULL)
/* VFS methods. */
-/* Allows for fchdir(2). */
+/* No longer used. */
#define CAP_FCHDIR CAPRIGHT(0, 0x0000000000000800ULL)
/* Allows for fchflags(2). */
#define CAP_FCHFLAGS CAPRIGHT(0, 0x0000000000001000ULL)
@@ -451,6 +451,7 @@
int cap_fcntl_check(struct filedesc *fdp, int fd, int cmd);
extern bool trap_enotcap;
+extern bool old_capsicum_semantics;
#else /* !_KERNEL */
diff --git a/usr.bin/procstat/procstat_files.c b/usr.bin/procstat/procstat_files.c
--- a/usr.bin/procstat/procstat_files.c
+++ b/usr.bin/procstat/procstat_files.c
@@ -145,7 +145,6 @@
{ CAP_FTRUNCATE, "ft" },
/* VFS methods. */
- { CAP_FCHDIR, "cd" },
{ CAP_FCHFLAGS, "cf" },
{ CAP_FCHMOD, "cm" },
{ CAP_FCHOWN, "cn" },
diff --git a/usr.sbin/chroot/chroot.8 b/usr.sbin/chroot/chroot.8
--- a/usr.sbin/chroot/chroot.8
+++ b/usr.sbin/chroot/chroot.8
@@ -33,6 +33,7 @@
.Nd change root directory
.Sh SYNOPSIS
.Nm
+.Op Fl d
.Op Fl G Ar group Ns Op Cm \&, Ns Ar group ...
.Op Fl g Ar group
.Op Fl u Ar user
@@ -51,6 +52,10 @@
.Pp
The options are as follows:
.Bl -tag -width "-G group[,group ...]"
+.It Fl d
+Treat
+.Ar newroot
+as a file descriptor number.
.It Fl G Ar group Ns Op Cm \&, Ns Ar group ...
Run the command with the permissions of the specified groups.
.It Fl g Ar group
diff --git a/usr.sbin/chroot/chroot.c b/usr.sbin/chroot/chroot.c
--- a/usr.sbin/chroot/chroot.c
+++ b/usr.sbin/chroot/chroot.c
@@ -30,10 +30,12 @@
*/
#include <sys/types.h>
+#include <sys/capsicum.h>
#include <sys/procctl.h>
#include <ctype.h>
#include <err.h>
+#include <fcntl.h>
#include <grp.h>
#include <limits.h>
#include <paths.h>
@@ -55,16 +57,22 @@
const char *shell;
gid_t gid, *gidlist;
uid_t uid;
- int arg, ch, error, gids;
+ int arg, ch, cwd, error, fd, gids;
long ngroups_max;
- bool nonprivileged;
+ bool fd_not_path, nonprivileged, capsicate;
gid = 0;
uid = 0;
user = group = grouplist = NULL;
- nonprivileged = false;
- while ((ch = getopt(argc, argv, "G:g:u:n")) != -1) {
+ capsicate = fd_not_path = nonprivileged = false;
+ while ((ch = getopt(argc, argv, "CdG:g:u:n")) != -1) {
switch(ch) {
+ case 'C':
+ capsicate = true;
+ break;
+ case 'd':
+ fd_not_path = true;
+ break;
case 'u':
user = optarg;
if (*user == '\0')
@@ -153,8 +161,31 @@
err(1, "procctl");
}
- if (chdir(argv[0]) == -1 || chroot(".") == -1)
- err(1, "%s", argv[0]);
+ if (fd_not_path) {
+ if (capsicate) {
+ cwd = open(".", O_RDONLY | O_DIRECTORY);
+ if (cwd < 0)
+ err(1, ".");
+ error = cap_enter();
+ if (error != 0)
+ err(1, "cap_enter");
+ }
+
+ fd = (uid_t)strtoul(argv[0], &endp, 0);
+ if (*endp != '\0')
+ errx(1, "%s is not a number", argv[0]);
+ if (fchdir(cwd) == -1)
+ err(1, "fchdir");
+ if (fchroot(fd) == -1)
+ err(1, "fchroot");
+ } else {
+ if (capsicate)
+ errx(1, "-C requires -d");
+ if (chdir(argv[0]) == -1)
+ err(1, "%s", argv[0]);
+ if (chroot(".") == -1)
+ err(1, "chroot");
+ }
if (gids && setgroups(gids, gidlist) == -1)
err(1, "setgroups");
@@ -178,7 +209,8 @@
static void
usage(void)
{
- (void)fprintf(stderr, "usage: chroot [-g group] [-G group,group,...] "
+ (void)fprintf(stderr,
+ "usage: chroot [-C] [-d] [-g group] [-G group,group,...] "
"[-u user] [-n] newroot [command]\n");
exit(1);
}

File Metadata

Mime Type
text/plain
Expires
Mon, Feb 9, 6:39 AM (11 h, 44 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
28549324
Default Alt Text
D44373.id54425.diff (18 KB)

Event Timeline