Page MenuHomeFreeBSD

D38351.diff
No OneTemporary

D38351.diff

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

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)

Event Timeline