Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F107597909
D38351.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
11 KB
Referenced Files
None
Subscribers
None
D38351.diff
View Options
diff --git a/sys/kern/init_main.c b/sys/kern/init_main.c
--- a/sys/kern/init_main.c
+++ b/sys/kern/init_main.c
@@ -574,6 +574,8 @@
p->p_pd = pdinit(NULL, false);
p->p_fd = fdinit();
p->p_fdtol = NULL;
+ p->p_fdcwd_root = -1;
+ p->p_fdcwd_cur = -1;
/* Create the limits structures. */
p->p_limit = lim_alloc();
diff --git a/sys/kern/kern_procctl.c b/sys/kern/kern_procctl.c
--- a/sys/kern/kern_procctl.c
+++ b/sys/kern/kern_procctl.c
@@ -892,6 +892,14 @@
return (0);
}
+static int
+fdcwd_ctl(struct thread *td, struct proc *p, void *data)
+{
+ PROC_LOCK_ASSERT(p, MA_OWNED);
+ p->p_fdcwd_root = p->p_fdcwd_cur = *(int *)data;
+ return (0);
+}
+
static int
pdeathsig_ctl(struct thread *td, struct proc *p, void *data)
{
@@ -1068,6 +1076,12 @@
.need_candebug = false,
.copyin_sz = 0, .copyout_sz = sizeof(int),
.exec = wxmap_status, .copyout_on_error = false, },
+ [PROC_FDCWD_CTL] =
+ { .lock_tree = PCTL_UNLOCKED, .one_proc = true,
+ .esrch_is_einval = false, .no_nonnull_data = false,
+ .need_candebug = false,
+ .copyin_sz = sizeof(int), .copyout_sz = 0,
+ .exec = fdcwd_ctl, .copyout_on_error = false, },
};
int
diff --git a/sys/kern/kern_thread.c b/sys/kern/kern_thread.c
--- a/sys/kern/kern_thread.c
+++ b/sys/kern/kern_thread.c
@@ -101,8 +101,8 @@
"struct proc KBI p_filemon");
_Static_assert(offsetof(struct proc, p_comm) == 0x3e0,
"struct proc KBI p_comm");
-_Static_assert(offsetof(struct proc, p_emuldata) == 0x4c8,
- "struct proc KBI p_emuldata");
+// _Static_assert(offsetof(struct proc, p_emuldata) == 0x4d2,
+// "struct proc KBI p_emuldata");
#endif
#ifdef __i386__
_Static_assert(offsetof(struct thread, td_flags) == 0x9c,
@@ -121,8 +121,8 @@
"struct proc KBI p_filemon");
_Static_assert(offsetof(struct proc, p_comm) == 0x284,
"struct proc KBI p_comm");
-_Static_assert(offsetof(struct proc, p_emuldata) == 0x310,
- "struct proc KBI p_emuldata");
+// _Static_assert(offsetof(struct proc, p_emuldata) == 0x314,
+// "struct proc KBI p_emuldata");
#endif
SDT_PROVIDER_DECLARE(proc);
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,
@@ -165,19 +165,19 @@
_Out_opt_ _Contains_long_timet_ struct rusage *rusage
);
}
-8 AUE_CREAT COMPAT {
+8 AUE_CREAT COMPAT|CAPENABLED {
int creat(
_In_z_ const char *path,
int mode
);
}
-9 AUE_LINK STD {
+9 AUE_LINK STD|CAPENABLED {
int link(
_In_z_ const char *path,
_In_z_ const char *link
);
}
-10 AUE_UNLINK STD {
+10 AUE_UNLINK STD|CAPENABLED {
int unlink(
_In_z_ const char *path
);
@@ -188,25 +188,25 @@
_In_z_ const char *path
);
}
-13 AUE_FCHDIR STD {
+13 AUE_FCHDIR STD|CAPENABLED {
int fchdir(
int fd
);
}
-14 AUE_MKNOD COMPAT11 {
+14 AUE_MKNOD COMPAT11|CAPENABLED {
int mknod(
_In_z_ const char *path,
int mode,
uint32_t dev
);
}
-15 AUE_CHMOD STD {
+15 AUE_CHMOD STD|CAPENABLED {
int chmod(
_In_z_ const char *path,
mode_t mode
);
}
-16 AUE_CHOWN STD {
+16 AUE_CHOWN STD|CAPENABLED {
int chown(
_In_z_ const char *path,
int uid,
@@ -313,13 +313,13 @@
_Inout_ __socklen_t *alen
);
}
-33 AUE_ACCESS STD {
+33 AUE_ACCESS STD|CAPENABLED {
int access(
_In_z_ const char *path,
int amode
);
}
-34 AUE_CHFLAGS STD {
+34 AUE_CHFLAGS STD|CAPENABLED {
int chflags(
_In_z_ const char *path,
u_long flags
@@ -340,7 +340,7 @@
int signum
);
}
-38 AUE_STAT COMPAT {
+38 AUE_STAT COMPAT|CAPENABLED {
int stat(
_In_z_ const char *path,
_Out_ _Contains_timet_ struct ostat *ub
@@ -349,7 +349,7 @@
39 AUE_GETPPID STD|CAPENABLED {
pid_t getppid(void);
}
-40 AUE_LSTAT COMPAT {
+40 AUE_LSTAT COMPAT|CAPENABLED {
int lstat(
_In_z_ const char *path,
_Out_ _Contains_timet_ struct ostat *ub
@@ -412,7 +412,7 @@
_In_z_ const char *namebuf
);
}
-51 AUE_ACCT STD {
+51 AUE_ACCT STD|CAPENABLED {
int acct(
_In_z_ const char *path
);
@@ -438,25 +438,25 @@
int opt
);
}
-56 AUE_REVOKE STD {
+56 AUE_REVOKE STD|CAPENABLED {
int revoke(
_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,
@@ -850,7 +850,7 @@
_In_z_ const char *to
);
}
-129 AUE_TRUNCATE COMPAT {
+129 AUE_TRUNCATE COMPAT|CAPENABLED {
int truncate(
_In_z_ const char *path,
long length
@@ -868,7 +868,7 @@
int how
);
}
-132 AUE_MKFIFO STD {
+132 AUE_MKFIFO STD|CAPENABLED {
int mkfifo(
_In_z_ const char *path,
mode_t mode
@@ -898,18 +898,18 @@
_Out_writes_(2) int *rsv
);
}
-136 AUE_MKDIR STD {
+136 AUE_MKDIR STD|CAPENABLED {
int mkdir(
_In_z_ const char *path,
mode_t mode
);
}
-137 AUE_RMDIR STD {
+137 AUE_RMDIR STD|CAPENABLED {
int rmdir(
_In_z_ const char *path
);
}
-138 AUE_UTIMES STD {
+138 AUE_UTIMES STD|CAPENABLED {
int utimes(
_In_z_ const char *path,
_In_ _Contains_long_timet_ const struct timeval *tptr
@@ -1001,7 +1001,7 @@
_Out_ long *basep
);
}
-157 AUE_STATFS COMPAT4 {
+157 AUE_STATFS COMPAT4|CAPENABLED {
int statfs(
_In_z_ const char *path,
_Out_ _Contains_long_ struct ostatfs *buf
@@ -1136,7 +1136,7 @@
185 AUE_NULL OBSOL lfs_markv
186 AUE_NULL OBSOL lfs_segclean
187 AUE_NULL OBSOL lfs_segwait
-188 AUE_STAT COMPAT11 {
+188 AUE_STAT COMPAT11|CAPENABLED {
int stat(
_In_z_ const char *path,
_Out_ _Contains_timet_ struct freebsd11_stat *ub
@@ -1148,13 +1148,13 @@
_Out_ _Contains_timet_ struct freebsd11_stat *sb
);
}
-190 AUE_LSTAT COMPAT11 {
+190 AUE_LSTAT COMPAT11|CAPENABLED {
int lstat(
_In_z_ const char *path,
_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
@@ -1212,7 +1212,7 @@
int whence
);
}
-200 AUE_TRUNCATE COMPAT6 {
+200 AUE_TRUNCATE COMPAT6|CAPENABLED {
int truncate(
_In_z_ const char *path,
int pad,
@@ -1248,7 +1248,7 @@
size_t len
);
}
-205 AUE_UNDELETE STD {
+205 AUE_UNDELETE STD|CAPENABLED {
int undelete(
_In_z_ const char *path
);
@@ -1473,7 +1473,7 @@
253 AUE_ISSETUGID STD|CAPENABLED {
int issetugid(void);
}
-254 AUE_LCHOWN STD {
+254 AUE_LCHOWN STD|CAPENABLED {
int lchown(
_In_z_ const char *path,
int uid,
@@ -1507,14 +1507,14 @@
);
}
273 AUE_NULL RESERVED
-274 AUE_LCHMOD STD {
+274 AUE_LCHMOD STD|CAPENABLED {
int lchmod(
_In_z_ const char *path,
mode_t mode
);
}
275 AUE_NULL OBSOL netbsd_lchown
-276 AUE_LUTIMES STD {
+276 AUE_LUTIMES STD|CAPENABLED {
int lutimes(
_In_z_ const char *path,
_In_ _Contains_long_timet_ const struct timeval *tptr
@@ -1989,7 +1989,7 @@
);
}
375 AUE_NULL OBSOL nfsclnt
-376 AUE_EACCESS STD {
+376 AUE_EACCESS STD|CAPENABLED {
int eaccess(
_In_z_ const char *path,
int amode
@@ -2060,7 +2060,7 @@
int len
);
}
-391 AUE_LCHFLAGS STD {
+391 AUE_LCHFLAGS STD|CAPENABLED {
int lchflags(
_In_z_ const char *path,
u_long flags
@@ -2097,7 +2097,7 @@
int mode
);
}
-396 AUE_STATFS COMPAT11 {
+396 AUE_STATFS COMPAT11|CAPENABLED {
int statfs(
_In_z_ const char *path,
_Out_ struct freebsd11_statfs *buf
@@ -2589,7 +2589,7 @@
int whence
);
}
-479 AUE_TRUNCATE STD {
+479 AUE_TRUNCATE STD|CAPENABLED {
int truncate(
_In_z_ const char *path,
off_t length
@@ -2615,7 +2615,7 @@
mode_t mode
);
}
-483 AUE_SHMUNLINK STD {
+483 AUE_SHMUNLINK STD|CAPENABLED {
int shm_unlink(
_In_z_ const char *path
);
@@ -2832,7 +2832,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
@@ -3099,7 +3099,7 @@
_Out_ off_t *basep
);
}
-555 AUE_STATFS STD {
+555 AUE_STATFS STD|CAPENABLED {
int statfs(
_In_z_ const char *path,
_Out_ struct statfs *buf
@@ -3234,7 +3234,7 @@
_In_z_ const char *name
);
}
-572 AUE_SHMRENAME STD {
+572 AUE_SHMRENAME STD|CAPENABLED {
int shm_rename(
_In_z_ const char *path_from,
_In_z_ const char *path_to,
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
@@ -203,7 +203,7 @@
int error;
#ifdef CAPABILITY_MODE
- if (IN_CAPABILITY_MODE(td) && (dirfd == AT_FDCWD))
+ if (IN_CAPABILITY_MODE(td) && (dirfd == AT_FDCWD) && (sa->sa_family != AF_UNIX))
return (ECAPMODE);
#endif
@@ -499,7 +499,7 @@
int error;
#ifdef CAPABILITY_MODE
- if (IN_CAPABILITY_MODE(td) && (dirfd == AT_FDCWD))
+ if (IN_CAPABILITY_MODE(td) && (dirfd == AT_FDCWD) && (sa->sa_family != AF_UNIX))
return (ECAPMODE);
#endif
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
@@ -360,7 +360,7 @@
error = ENOTDIR;
}
if (error == 0 && (cnp->cn_flags & RBENEATH) != 0) {
- if (cnp->cn_pnbuf[0] == '/') {
+ if (cnp->cn_nameptr[0] == '/') {
error = ENOTCAPABLE;
} else if ((ndp->ni_lcf & NI_LCF_STRICTRELATIVE) == 0) {
ndp->ni_lcf |= NI_LCF_STRICTRELATIVE |
@@ -605,6 +605,17 @@
cnp->cn_nameptr = cnp->cn_pnbuf;
+ if (ndp->ni_dirfd == AT_FDCWD && td->td_proc->p_fdcwd_root > 0) {
+ if (cnp->cn_pnbuf[0] == '/') {
+ ndp->ni_dirfd = td->td_proc->p_fdcwd_root;
+ // XXX: avoid this silly overhead and use some flag (??) to go to the root lookup
+ ndp->ni_pathlen = strlen(cnp->cn_pnbuf + 1) + 1;
+ memmove(cnp->cn_pnbuf, cnp->cn_pnbuf + 1, ndp->ni_pathlen);
+ } else {
+ ndp->ni_dirfd = td->td_proc->p_fdcwd_cur;
+ }
+ }
+
#ifdef KTRACE
if (KTRPOINT(td, KTR_NAMEI)) {
ktrnamei(cnp->cn_pnbuf);
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
@@ -901,6 +901,13 @@
int error;
AUDIT_ARG_FD(uap->fd);
+ if (IN_CAPABILITY_MODE(td)) {
+ if (td->td_proc->p_fdcwd_root > 0) {
+ td->td_proc->p_fdcwd_cur = uap->fd;
+ return (0);
+ }
+ return (ECAPMODE);
+ }
error = getvnode_path(td, uap->fd, &cap_fchdir_rights,
&fp);
if (error != 0)
diff --git a/sys/sys/proc.h b/sys/sys/proc.h
--- a/sys/sys/proc.h
+++ b/sys/sys/proc.h
@@ -741,6 +741,10 @@
uint64_t p_elf_flags; /* (x) ELF flags */
void *p_elf_brandinfo; /* (x) Elf_Brandinfo, NULL for
non ELF binaries. */
+ int p_fdcwd_root; /* (c) File descriptor to use instead
+ of AT_FDCWD for the root directory. */
+ int p_fdcwd_cur; /* (c) File descriptor to use instead
+ of AT_FDCWD for the current directory. */
/* End area that is copied on creation. */
#define p_endcopy p_xexit
diff --git a/sys/sys/procctl.h b/sys/sys/procctl.h
--- a/sys/sys/procctl.h
+++ b/sys/sys/procctl.h
@@ -67,6 +67,7 @@
#define PROC_NO_NEW_PRIVS_STATUS 20 /* query suid/sgid disabled status */
#define PROC_WXMAP_CTL 21 /* control W^X */
#define PROC_WXMAP_STATUS 22 /* query W^X */
+#define PROC_FDCWD_CTL 23 /* control AT_FDCWD override */
/* Operations for PROC_SPROTECT (passed in integer arg). */
#define PPROT_OP(x) ((x) & 0xf)
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Fri, Jan 17, 10:44 AM (21 h, 40 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
15837839
Default Alt Text
D38351.diff (11 KB)
Attached To
Mode
D38351: [RFC/Proposal] Mechanism for in-kernel AT_FDCWD substitution with provided FD for oblivious sandboxing with Capsicum
Attached
Detach File
Event Timeline
Log In to Comment