Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F107598874
D41564.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
8 KB
Referenced Files
None
Subscribers
None
D41564.diff
View Options
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
@@ -399,6 +399,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
@@ -378,6 +378,7 @@
};
FBSD_1.8 {
+ fchroot;
getrlimitusage;
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
@@ -3341,5 +3341,10 @@
_Out_ rlim_t *res
);
}
+590 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
Details
Attached
Mime Type
text/plain
Expires
Fri, Jan 17, 11:03 AM (21 h, 26 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
15838048
Default Alt Text
D41564.diff (8 KB)
Attached To
Mode
D41564: Add fchroot(2)
Attached
Detach File
Event Timeline
Log In to Comment