Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F142269619
D54592.id169290.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
13 KB
Referenced Files
None
Subscribers
None
D54592.id169290.diff
View Options
diff --git a/contrib/openbsm/sys/bsm/audit_kevents.h b/contrib/openbsm/sys/bsm/audit_kevents.h
--- a/contrib/openbsm/sys/bsm/audit_kevents.h
+++ b/contrib/openbsm/sys/bsm/audit_kevents.h
@@ -655,6 +655,7 @@
#define AUE_SHMRENAME 43263 /* FreeBSD-specific. */
#define AUE_REALPATHAT 43264 /* FreeBSD-specific. */
#define AUE_CLOSERANGE 43265 /* FreeBSD-specific. */
+#define AUE_PDRFORK 43266 /* FreeBSD-specific. */
/*
* Darwin BSM uses a number of AUE_O_* definitions, which are aliased to the
diff --git a/lib/libc/gen/exterr_cat_filenames.h b/lib/libc/gen/exterr_cat_filenames.h
--- a/lib/libc/gen/exterr_cat_filenames.h
+++ b/lib/libc/gen/exterr_cat_filenames.h
@@ -8,10 +8,11 @@
[EXTERR_CAT_GEOM] = "geom/geom_subr.c",
[EXTERR_CAT_GEOMVFS] = "geom/geom_vfs.c",
[EXTERR_CAT_FILEDESC] = "kern/kern_descrip.c",
- [EXTERR_CAT_INOTIFY] = "kern/vfs_inotify.c",
+ [EXTERR_CAT_FORK] = "kern/kern_fork.c",
[EXTERR_CAT_GENIO] = "kern/sys_generic.c",
[EXTERR_CAT_VFSBIO] = "kern/vfs_bio.c",
[EXTERR_CAT_VFSSYSCALL] = "kern/vfs_syscalls.c",
+ [EXTERR_CAT_INOTIFY] = "kern/vfs_inotify.c",
[EXTERR_CAT_BRIDGE] = "net/if_bridge.c",
[EXTERR_CAT_SWAP] = "vm/swap_pager.c",
[EXTERR_CAT_MMAP] = "vm/vm_mmap.c",
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
@@ -389,6 +389,10 @@
setgroups;
};
+FBSD_1.9 {
+ pdrfork;
+};
+
FBSDprivate_1.0 {
/* Add entries in sort(1) order */
__set_error_selector;
diff --git a/lib/libsys/_libsys.h b/lib/libsys/_libsys.h
--- a/lib/libsys/_libsys.h
+++ b/lib/libsys/_libsys.h
@@ -472,6 +472,7 @@
typedef int (__sys_jail_attach_jd_t)(int);
typedef int (__sys_jail_remove_jd_t)(int);
typedef int (__sys_kexec_load_t)(uint64_t, u_long, struct kexec_segment *, u_long);
+typedef int (__sys_pdrfork_t)(int *, int, int);
_Noreturn void __sys__exit(int rval);
int __sys_fork(void);
@@ -879,6 +880,7 @@
int __sys_jail_attach_jd(int fd);
int __sys_jail_remove_jd(int fd);
int __sys_kexec_load(uint64_t entry, u_long nseg, struct kexec_segment * segments, u_long flags);
+int __sys_pdrfork(int * fdp, int pdflags, int rfflags);
__END_DECLS
#endif /* __LIBSYS_H_ */
diff --git a/lib/libsys/syscalls.map b/lib/libsys/syscalls.map
--- a/lib/libsys/syscalls.map
+++ b/lib/libsys/syscalls.map
@@ -819,4 +819,6 @@
__sys_jail_remove_jd;
_kexec_load;
__sys_kexec_load;
+ _pdrfork;
+ __sys_pdrfork;
};
diff --git a/sys/bsm/audit_kevents.h b/sys/bsm/audit_kevents.h
--- a/sys/bsm/audit_kevents.h
+++ b/sys/bsm/audit_kevents.h
@@ -664,6 +664,7 @@
#define AUE_TIMERFD 43270 /* FreeBSD/Linux. */
#define AUE_SETCRED 43271 /* FreeBSD-specific. */
#define AUE_INOTIFY 43272 /* FreeBSD/Linux. */
+#define AUE_PDRFORK 43266 /* FreeBSD-specific. */
/*
* Darwin BSM uses a number of AUE_O_* definitions, which are aliased to the
diff --git a/sys/compat/freebsd32/freebsd32_syscall.h b/sys/compat/freebsd32/freebsd32_syscall.h
--- a/sys/compat/freebsd32/freebsd32_syscall.h
+++ b/sys/compat/freebsd32/freebsd32_syscall.h
@@ -517,4 +517,5 @@
#define FREEBSD32_SYS_setgroups 596
#define FREEBSD32_SYS_jail_attach_jd 597
#define FREEBSD32_SYS_jail_remove_jd 598
-#define FREEBSD32_SYS_MAXSYSCALL 600
+#define FREEBSD32_SYS_pdrfork 600
+#define FREEBSD32_SYS_MAXSYSCALL 601
diff --git a/sys/compat/freebsd32/freebsd32_syscalls.c b/sys/compat/freebsd32/freebsd32_syscalls.c
--- a/sys/compat/freebsd32/freebsd32_syscalls.c
+++ b/sys/compat/freebsd32/freebsd32_syscalls.c
@@ -605,4 +605,5 @@
"jail_attach_jd", /* 597 = jail_attach_jd */
"jail_remove_jd", /* 598 = jail_remove_jd */
"#599", /* 599 = kexec_load */
+ "pdrfork", /* 600 = pdrfork */
};
diff --git a/sys/compat/freebsd32/freebsd32_sysent.c b/sys/compat/freebsd32/freebsd32_sysent.c
--- a/sys/compat/freebsd32/freebsd32_sysent.c
+++ b/sys/compat/freebsd32/freebsd32_sysent.c
@@ -667,4 +667,5 @@
{ .sy_narg = AS(jail_attach_jd_args), .sy_call = (sy_call_t *)sys_jail_attach_jd, .sy_auevent = AUE_JAIL_ATTACH, .sy_flags = 0, .sy_thrcnt = SY_THR_STATIC }, /* 597 = jail_attach_jd */
{ .sy_narg = AS(jail_remove_jd_args), .sy_call = (sy_call_t *)sys_jail_remove_jd, .sy_auevent = AUE_JAIL_REMOVE, .sy_flags = 0, .sy_thrcnt = SY_THR_STATIC }, /* 598 = jail_remove_jd */
{ .sy_narg = 0, .sy_call = (sy_call_t *)nosys, .sy_auevent = AUE_NULL, .sy_flags = 0, .sy_thrcnt = SY_THR_ABSENT }, /* 599 = freebsd32_kexec_load */
+ { .sy_narg = AS(pdrfork_args), .sy_call = (sy_call_t *)sys_pdrfork, .sy_auevent = AUE_PDRFORK, .sy_flags = SYF_CAPENABLED, .sy_thrcnt = SY_THR_STATIC }, /* 600 = pdrfork */
};
diff --git a/sys/compat/freebsd32/freebsd32_systrace_args.c b/sys/compat/freebsd32/freebsd32_systrace_args.c
--- a/sys/compat/freebsd32/freebsd32_systrace_args.c
+++ b/sys/compat/freebsd32/freebsd32_systrace_args.c
@@ -3427,6 +3427,15 @@
*n_args = 1;
break;
}
+ /* pdrfork */
+ case 600: {
+ struct pdrfork_args *p = params;
+ uarg[a++] = (intptr_t)p->fdp; /* int * */
+ iarg[a++] = p->pdflags; /* int */
+ iarg[a++] = p->rfflags; /* int */
+ *n_args = 3;
+ break;
+ }
default:
*n_args = 0;
break;
@@ -9256,6 +9265,22 @@
break;
};
break;
+ /* pdrfork */
+ case 600:
+ switch (ndx) {
+ case 0:
+ p = "userland int *";
+ break;
+ case 1:
+ p = "int";
+ break;
+ case 2:
+ p = "int";
+ break;
+ default:
+ break;
+ };
+ break;
default:
break;
};
@@ -11174,6 +11199,11 @@
if (ndx == 0 || ndx == 1)
p = "int";
break;
+ /* pdrfork */
+ case 600:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
default:
break;
};
diff --git a/sys/kern/init_sysent.c b/sys/kern/init_sysent.c
--- a/sys/kern/init_sysent.c
+++ b/sys/kern/init_sysent.c
@@ -666,4 +666,5 @@
{ .sy_narg = AS(jail_attach_jd_args), .sy_call = (sy_call_t *)sys_jail_attach_jd, .sy_auevent = AUE_JAIL_ATTACH, .sy_flags = 0, .sy_thrcnt = SY_THR_STATIC }, /* 597 = jail_attach_jd */
{ .sy_narg = AS(jail_remove_jd_args), .sy_call = (sy_call_t *)sys_jail_remove_jd, .sy_auevent = AUE_JAIL_REMOVE, .sy_flags = 0, .sy_thrcnt = SY_THR_STATIC }, /* 598 = jail_remove_jd */
{ .sy_narg = AS(kexec_load_args), .sy_call = (sy_call_t *)sys_kexec_load, .sy_auevent = AUE_NULL, .sy_flags = 0, .sy_thrcnt = SY_THR_STATIC }, /* 599 = kexec_load */
+ { .sy_narg = AS(pdrfork_args), .sy_call = (sy_call_t *)sys_pdrfork, .sy_auevent = AUE_PDRFORK, .sy_flags = SYF_CAPENABLED, .sy_thrcnt = SY_THR_STATIC }, /* 600 = pdrfork */
};
diff --git a/sys/kern/kern_fork.c b/sys/kern/kern_fork.c
--- a/sys/kern/kern_fork.c
+++ b/sys/kern/kern_fork.c
@@ -34,20 +34,22 @@
* SUCH DAMAGE.
*/
-#include <sys/cdefs.h>
#include "opt_ktrace.h"
#include "opt_kstack_pages.h"
-#include <sys/param.h>
+#define EXTERR_CATEGORY EXTERR_CAT_FORK
#include <sys/systm.h>
+#include <sys/acct.h>
#include <sys/bitstring.h>
-#include <sys/sysproto.h>
#include <sys/eventhandler.h>
+#include <sys/exterrvar.h>
#include <sys/fcntl.h>
#include <sys/filedesc.h>
#include <sys/jail.h>
#include <sys/kernel.h>
#include <sys/kthread.h>
+#include <sys/ktr.h>
+#include <sys/ktrace.h>
#include <sys/sysctl.h>
#include <sys/lock.h>
#include <sys/malloc.h>
@@ -60,17 +62,15 @@
#include <sys/racct.h>
#include <sys/resourcevar.h>
#include <sys/sched.h>
+#include <sys/sdt.h>
+#include <sys/signalvar.h>
+#include <sys/sx.h>
#include <sys/syscall.h>
+#include <sys/sysent.h>
+#include <sys/sysproto.h>
#include <sys/vmmeter.h>
#include <sys/vnode.h>
-#include <sys/acct.h>
-#include <sys/ktr.h>
-#include <sys/ktrace.h>
#include <sys/unistd.h>
-#include <sys/sdt.h>
-#include <sys/sx.h>
-#include <sys/sysent.h>
-#include <sys/signalvar.h>
#include <security/audit/audit.h>
#include <security/mac/mac_framework.h>
@@ -188,6 +188,65 @@
return (error);
}
+int
+sys_pdrfork(struct thread *td, struct pdrfork_args *uap)
+{
+ struct fork_req fr;
+ struct proc *p;
+ int error, fd, pid;
+
+ bzero(&fr, sizeof(fr));
+ fd = -1;
+ p = NULL;
+
+ AUDIT_ARG_FFLAGS(uap->rfflags);
+ /* XXXKIB AUDIT_ARG_PDLAGS(uap->pdflags); */
+
+ if ((uap->rfflags & RFPROCDESC) == 0)
+ return (EXTERROR(EINVAL,
+ "Must specify RFPROCDESC %#jx", uap->rfflags));
+
+ /* RFSPAWN must not appear with others */
+ if ((uap->rfflags & RFSPAWN) != 0) {
+ if (uap->rfflags != (RFSPAWN | RFPROCDESC))
+ return (EXTERROR(EINVAL,
+ "RFSPAWN must be the only flag %#jx",
+ uap->rfflags));
+ fr.fr_flags = RFFDG | RFPROC | RFPPWAIT | RFMEM | RFPROCDESC;
+ fr.fr_flags2 = FR2_DROPSIG_CAUGHT;
+ } else {
+ if ((uap->rfflags & (RFSTOPPED | RFHIGHPID)) != 0)
+ return (EXTERROR(EINVAL, "Disallowed rfflags %#jx",
+ uap->rfflags));
+ fr.fr_flags = uap->rfflags;
+ if ((uap->rfflags & RFPROC) == 0) {
+ error = copyin(uap->fdp, &fd, sizeof(fd));
+ if (error != 0)
+ return (error);
+ error = procdesc_find(td, fd, &cap_pdkill_rights, &p);
+ if (error != 0)
+ return (error);
+ PROC_UNLOCK(p);
+ if (p != curproc)
+ return (EXTERROR(EBUSY, "Target must be me"));
+ p = NULL;
+ }
+ }
+
+ fr.fr_procp = &p;
+ fr.fr_pidp = &pid;
+ fr.fr_pd_fd = &fd;
+ fr.fr_pd_flags = uap->pdflags;
+ error = fork1(td, &fr);
+ if (error == 0) {
+ td->td_retval[0] = pid;
+ td->td_retval[1] = 0;
+ if ((fr.fr_flags & RFPROC) != 0)
+ error = copyout(&fd, uap->fdp, sizeof(fd));
+ }
+ return (error);
+}
+
int __exclusive_cache_line nprocs = 1; /* process 0 */
int lastpid = 0;
SYSCTL_INT(_kern, OID_AUTO, lastpid, CTLFLAG_RD, &lastpid, 0,
diff --git a/sys/kern/syscalls.c b/sys/kern/syscalls.c
--- a/sys/kern/syscalls.c
+++ b/sys/kern/syscalls.c
@@ -605,4 +605,5 @@
"jail_attach_jd", /* 597 = jail_attach_jd */
"jail_remove_jd", /* 598 = jail_remove_jd */
"kexec_load", /* 599 = kexec_load */
+ "pdrfork", /* 600 = pdrfork */
};
diff --git a/sys/kern/syscalls.master b/sys/kern/syscalls.master
--- a/sys/kern/syscalls.master
+++ b/sys/kern/syscalls.master
@@ -3402,4 +3402,13 @@
u_long flags
);
}
+
+600 AUE_PDRFORK STD|CAPENABLED {
+ int pdrfork(
+ _Out_ int *fdp,
+ int pdflags,
+ int rfflags
+ );
+ }
+
; vim: syntax=off
diff --git a/sys/kern/systrace_args.c b/sys/kern/systrace_args.c
--- a/sys/kern/systrace_args.c
+++ b/sys/kern/systrace_args.c
@@ -3524,6 +3524,15 @@
*n_args = 4;
break;
}
+ /* pdrfork */
+ case 600: {
+ struct pdrfork_args *p = params;
+ uarg[a++] = (intptr_t)p->fdp; /* int * */
+ iarg[a++] = p->pdflags; /* int */
+ iarg[a++] = p->rfflags; /* int */
+ *n_args = 3;
+ break;
+ }
default:
*n_args = 0;
break;
@@ -9430,6 +9439,22 @@
break;
};
break;
+ /* pdrfork */
+ case 600:
+ switch (ndx) {
+ case 0:
+ p = "userland int *";
+ break;
+ case 1:
+ p = "int";
+ break;
+ case 2:
+ p = "int";
+ break;
+ default:
+ break;
+ };
+ break;
default:
break;
};
@@ -11443,6 +11468,11 @@
if (ndx == 0 || ndx == 1)
p = "int";
break;
+ /* pdrfork */
+ case 600:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
default:
break;
};
diff --git a/sys/security/audit/audit_bsm.c b/sys/security/audit/audit_bsm.c
--- a/sys/security/audit/audit_bsm.c
+++ b/sys/security/audit/audit_bsm.c
@@ -1100,6 +1100,17 @@
FD_VNODE1_TOKENS;
break;
+ case AUE_PDFORK:
+ if (ARG_IS_VALID(kar, ARG_XXX)) {
+ tok = au_to_arg32(1, "flags", ar->ar_arg_xxlags);
+ kau_write(rec, tok);
+ }
+ if (ARG_IS_VALID(kar, ARG_FD)) {
+ tok = au_to_arg32(1, "fd", ar->ar_arg_fd);
+ kau_write(rec, tok);
+ }
+ /* FALLTHROUGH */
+
case AUE_RFORK:
if (ARG_IS_VALID(kar, ARG_FFLAGS)) {
tok = au_to_arg32(1, "flags", ar->ar_arg_fflags);
diff --git a/sys/sys/exterr_cat.h b/sys/sys/exterr_cat.h
--- a/sys/sys/exterr_cat.h
+++ b/sys/sys/exterr_cat.h
@@ -37,6 +37,7 @@
#define EXTERR_CAT_GEOM 12
#define EXTERR_CAT_FUSE_VFS 13
#define EXTERR_CAT_FUSE_DEVICE 14
+#define EXTERR_CAT_FORK 15
#endif
diff --git a/sys/sys/procdesc.h b/sys/sys/procdesc.h
--- a/sys/sys/procdesc.h
+++ b/sys/sys/procdesc.h
@@ -123,6 +123,7 @@
*/
__BEGIN_DECLS
pid_t pdfork(int *, int);
+pid_t pdrfork(int *, int, int);
int pdkill(int, int);
int pdgetpid(int, pid_t *);
__END_DECLS
diff --git a/sys/sys/syscall.h b/sys/sys/syscall.h
--- a/sys/sys/syscall.h
+++ b/sys/sys/syscall.h
@@ -538,4 +538,5 @@
#define SYS_jail_attach_jd 597
#define SYS_jail_remove_jd 598
#define SYS_kexec_load 599
-#define SYS_MAXSYSCALL 600
+#define SYS_pdrfork 600
+#define SYS_MAXSYSCALL 601
diff --git a/sys/sys/syscall.mk b/sys/sys/syscall.mk
--- a/sys/sys/syscall.mk
+++ b/sys/sys/syscall.mk
@@ -441,4 +441,5 @@
setgroups.o \
jail_attach_jd.o \
jail_remove_jd.o \
- kexec_load.o
+ kexec_load.o \
+ pdrfork.o
diff --git a/sys/sys/sysproto.h b/sys/sys/sysproto.h
--- a/sys/sys/sysproto.h
+++ b/sys/sys/sysproto.h
@@ -1913,6 +1913,11 @@
char segments_l_[PADL_(struct kexec_segment *)]; struct kexec_segment * segments; char segments_r_[PADR_(struct kexec_segment *)];
char flags_l_[PADL_(u_long)]; u_long flags; char flags_r_[PADR_(u_long)];
};
+struct pdrfork_args {
+ char fdp_l_[PADL_(int *)]; int * fdp; char fdp_r_[PADR_(int *)];
+ char pdflags_l_[PADL_(int)]; int pdflags; char pdflags_r_[PADR_(int)];
+ char rfflags_l_[PADL_(int)]; int rfflags; char rfflags_r_[PADR_(int)];
+};
int sys__exit(struct thread *, struct _exit_args *);
int sys_fork(struct thread *, struct fork_args *);
int sys_read(struct thread *, struct read_args *);
@@ -2320,6 +2325,7 @@
int sys_jail_attach_jd(struct thread *, struct jail_attach_jd_args *);
int sys_jail_remove_jd(struct thread *, struct jail_remove_jd_args *);
int sys_kexec_load(struct thread *, struct kexec_load_args *);
+int sys_pdrfork(struct thread *, struct pdrfork_args *);
#ifdef COMPAT_43
@@ -3319,6 +3325,7 @@
#define SYS_AUE_jail_attach_jd AUE_JAIL_ATTACH
#define SYS_AUE_jail_remove_jd AUE_JAIL_REMOVE
#define SYS_AUE_kexec_load AUE_NULL
+#define SYS_AUE_pdrfork AUE_PDRFORK
#undef PAD_
#undef PADL_
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Mon, Jan 19, 12:23 AM (20 h, 3 s)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
27723218
Default Alt Text
D54592.id169290.diff (13 KB)
Attached To
Mode
D54592: Add pdrfork(2) and pdwait(2)
Attached
Detach File
Event Timeline
Log In to Comment