Page MenuHomeFreeBSD

D41564.diff
No OneTemporary

D41564.diff

diff --git a/include/unistd.h b/include/unistd.h
--- a/include/unistd.h
+++ b/include/unistd.h
@@ -507,6 +507,7 @@
int execvP(const char *, const char *, char * const *);
int execvpe(const char *, char * const *, char * const *);
int feature_present(const char *);
+int fchroot(int);
char *fflagstostr(u_long);
int getdomainname(char *, int);
int getentropy(void *, size_t);
diff --git a/lib/libsys/Makefile.sys b/lib/libsys/Makefile.sys
--- a/lib/libsys/Makefile.sys
+++ b/lib/libsys/Makefile.sys
@@ -403,6 +403,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
@@ -379,6 +379,7 @@
};
FBSD_1.8 {
+ fchroot;
kcmp;
};
diff --git a/lib/libsys/chroot.2 b/lib/libsys/chroot.2
--- a/lib/libsys/chroot.2
+++ b/lib/libsys/chroot.2
@@ -25,11 +25,12 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.Dd September 29, 2020
+.Dd July 15, 2024
.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
+system call is identical to
+.Fn chroot
+except it takes a file descriptor instead of path.
.Sh RETURN VALUES
.Rv -std
.Sh ERRORS
@@ -124,6 +133,29 @@
.It Bq Er EINTEGRITY
Corrupted data was detected while reading from the file system.
.El
+.Pp
+The
+.Fn fchroot
+system call
+will fail and the root directory will be unchanged if:
+.Bl -tag -width Er
+.It Bq Er EACCES
+Search permission is denied for the directory referenced by the
+file descriptor.
+.It Bq Er EBADF
+The argument
+.Fa fd
+is not a valid file descriptor.
+.It Bq Er EIO
+An I/O error occurred while reading from or writing to the file system.
+.It Bq Er EINTEGRITY
+Corrupted data was detected while reading from the file system.
+.It Bq Er ENOTDIR
+The file descriptor does not reference a directory.
+.It Bq Er EPERM
+The effective user ID is not the super-user, or one or more
+filedescriptors are open directories.
+.El
.Sh SEE ALSO
.Xr chdir 2 ,
.Xr jail 2
@@ -137,6 +169,10 @@
in
.St -susv2 ,
and was removed in subsequent standards.
+The
+.Fn fchroot
+system call first appeared in
+.Fx 15.0 .
.Sh BUGS
If the process is able to change its working directory to the target
directory, but another access control check fails (such as a check for
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
@@ -30,7 +30,7 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.Dd April 27, 2024
+.Dd May 1, 2024
.Dt RIGHTS 4
.Os
.Sh NAME
@@ -209,6 +209,9 @@
.Dv CAP_FCHOWN
and
.Dv CAP_LOOKUP .
+.It Dv CAP_FCHROOT
+Permit
+.Xr fchroot 2 .
.It Dv CAP_FCNTL
Permit
.Xr fcntl 2 .
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
@@ -59,6 +59,7 @@
__read_mostly cap_rights_t cap_fchflags_rights;
__read_mostly cap_rights_t cap_fchmod_rights;
__read_mostly cap_rights_t cap_fchown_rights;
+__read_mostly cap_rights_t cap_fchroot_rights;
__read_mostly cap_rights_t cap_fcntl_rights;
__read_mostly cap_rights_t cap_fexecve_rights;
__read_mostly cap_rights_t cap_flock_rights;
@@ -108,6 +109,7 @@
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);
+ cap_rights_init_one(&cap_fchroot_rights, CAP_FCHROOT);
cap_rights_init_one(&cap_fcntl_rights, CAP_FCNTL);
cap_rights_init_one(&cap_fexecve_rights, CAP_FEXECVE);
cap_rights_init_one(&cap_flock_rights, CAP_FLOCK);
diff --git a/sys/kern/syscalls.master b/sys/kern/syscalls.master
--- a/sys/kern/syscalls.master
+++ b/sys/kern/syscalls.master
@@ -3333,5 +3333,10 @@
uintptr_t idx2
);
}
+589 AUE_NULL STD {
+ int fchroot(
+ int fd
+ );
+ }
; vim: syntax=off
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
@@ -967,18 +967,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 +984,75 @@
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);
+}
+
+/*
+ * Change notion of root directory to a given file descriptor.
+ */
+#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;
+
+ error = getvnode_path(td, uap->fd, &cap_fchroot_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
@@ -66,6 +66,7 @@
extern cap_rights_t cap_fchflags_rights;
extern cap_rights_t cap_fchmod_rights;
extern cap_rights_t cap_fchown_rights;
+extern cap_rights_t cap_fchroot_rights;
extern cap_rights_t cap_fcntl_rights;
extern cap_rights_t cap_fexecve_rights;
extern cap_rights_t cap_flock_rights;
diff --git a/sys/sys/capsicum.h b/sys/sys/capsicum.h
--- a/sys/sys/capsicum.h
+++ b/sys/sys/capsicum.h
@@ -201,6 +201,9 @@
/* Allows for renameat(2) (target directory descriptor). */
#define CAP_RENAMEAT_TARGET (CAP_LOOKUP | 0x0000040000000000ULL)
+/* Allows for fchroot(2). */
+#define CAP_FCHROOT CAPRIGHT(0, 0x0000080000000000ULL)
+
#define CAP_SOCK_CLIENT \
(CAP_CONNECT | CAP_GETPEERNAME | CAP_GETSOCKNAME | CAP_GETSOCKOPT | \
CAP_PEELOFF | CAP_RECV | CAP_SEND | CAP_SETSOCKOPT | CAP_SHUTDOWN)
@@ -210,11 +213,9 @@
CAP_SETSOCKOPT | CAP_SHUTDOWN)
/* All used bits for index 0. */
-#define CAP_ALL0 CAPRIGHT(0, 0x000007FFFFFFFFFFULL)
+#define CAP_ALL0 CAPRIGHT(0, 0x00000FFFFFFFFFFFULL)
/* Available bits for index 0. */
-#define CAP_UNUSED0_44 CAPRIGHT(0, 0x0000080000000000ULL)
-/* ... */
#define CAP_UNUSED0_57 CAPRIGHT(0, 0x0100000000000000ULL)
/* INDEX 1 */
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
@@ -149,6 +149,7 @@
{ CAP_FCHFLAGS, "cf" },
{ CAP_FCHMOD, "cm" },
{ CAP_FCHOWN, "cn" },
+ { CAP_FCHROOT, "ct" },
{ CAP_FCNTL, "fc" },
{ CAP_FLOCK, "fl" },
{ CAP_FPATHCONF, "fp" },

File Metadata

Mime Type
text/plain
Expires
Sat, Oct 19, 5:06 AM (20 h, 27 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
14259376
Default Alt Text
D41564.diff (8 KB)

Event Timeline