Page MenuHomeFreeBSD

D57124.id178293.diff
No OneTemporary

D57124.id178293.diff

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
@@ -391,6 +391,7 @@
};
FBSD_1.9 {
+ pdopenpid;
pdrfork;
pdrfork_thread;
renameat2;
diff --git a/lib/libsys/_libsys.h b/lib/libsys/_libsys.h
--- a/lib/libsys/_libsys.h
+++ b/lib/libsys/_libsys.h
@@ -475,6 +475,7 @@
typedef int (__sys_pdrfork_t)(int *, int, int);
typedef int (__sys_pdwait_t)(int, int *, int, struct __wrusage *, struct __siginfo *);
typedef int (__sys_renameat2_t)(int, const char *, int, const char *, int);
+typedef int (__sys_pdopenpid_t)(pid_t, int);
_Noreturn void __sys__exit(int rval);
int __sys_fork(void);
@@ -885,6 +886,7 @@
int __sys_pdrfork(int * fdp, int pdflags, int rfflags);
int __sys_pdwait(int fd, int * status, int options, struct __wrusage * wrusage, struct __siginfo * info);
int __sys_renameat2(int oldfd, const char * old, int newfd, const char * new, int flags);
+int __sys_pdopenpid(pid_t pid, int flags);
__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
@@ -825,4 +825,6 @@
__sys_pdwait;
_renameat2;
__sys_renameat2;
+ _pdopenpid;
+ __sys_pdopenpid;
};
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
@@ -665,6 +665,7 @@
#define AUE_SETCRED 43271 /* FreeBSD-specific. */
#define AUE_INOTIFY 43272 /* FreeBSD/Linux. */
#define AUE_PDRFORK 43273 /* FreeBSD-specific. */
+#define AUE_PDOPENPID 43274 /* 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
@@ -520,4 +520,5 @@
#define FREEBSD32_SYS_pdrfork 600
#define FREEBSD32_SYS_freebsd32_pdwait 601
#define FREEBSD32_SYS_renameat2 602
-#define FREEBSD32_SYS_MAXSYSCALL 603
+#define FREEBSD32_SYS_pdopenpid 603
+#define FREEBSD32_SYS_MAXSYSCALL 604
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
@@ -608,4 +608,5 @@
"pdrfork", /* 600 = pdrfork */
"freebsd32_pdwait", /* 601 = freebsd32_pdwait */
"renameat2", /* 602 = renameat2 */
+ "pdopenpid", /* 603 = pdopenpid */
};
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
@@ -670,4 +670,5 @@
{ .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 */
{ .sy_narg = AS(freebsd32_pdwait_args), .sy_call = (sy_call_t *)freebsd32_pdwait, .sy_auevent = AUE_PDWAIT, .sy_flags = SYF_CAPENABLED, .sy_thrcnt = SY_THR_STATIC }, /* 601 = freebsd32_pdwait */
{ .sy_narg = AS(renameat2_args), .sy_call = (sy_call_t *)sys_renameat2, .sy_auevent = AUE_RENAMEAT, .sy_flags = SYF_CAPENABLED, .sy_thrcnt = SY_THR_STATIC }, /* 602 = renameat2 */
+ { .sy_narg = AS(pdopenpid_args), .sy_call = (sy_call_t *)sys_pdopenpid, .sy_auevent = AUE_PDOPENPID, .sy_flags = 0, .sy_thrcnt = SY_THR_STATIC }, /* 603 = pdopenpid */
};
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
@@ -3458,6 +3458,14 @@
*n_args = 5;
break;
}
+ /* pdopenpid */
+ case 603: {
+ struct pdopenpid_args *p = params;
+ iarg[a++] = p->pid; /* pid_t */
+ iarg[a++] = p->flags; /* int */
+ *n_args = 2;
+ break;
+ }
default:
*n_args = 0;
break;
@@ -9347,6 +9355,19 @@
break;
};
break;
+ /* pdopenpid */
+ case 603:
+ switch (ndx) {
+ case 0:
+ p = "pid_t";
+ break;
+ case 1:
+ p = "int";
+ break;
+ default:
+ break;
+ };
+ break;
default:
break;
};
@@ -11280,6 +11301,11 @@
if (ndx == 0 || ndx == 1)
p = "int";
break;
+ /* pdopenpid */
+ case 603:
+ 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
@@ -669,4 +669,5 @@
{ .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 */
{ .sy_narg = AS(pdwait_args), .sy_call = (sy_call_t *)sys_pdwait, .sy_auevent = AUE_PDWAIT, .sy_flags = SYF_CAPENABLED, .sy_thrcnt = SY_THR_STATIC }, /* 601 = pdwait */
{ .sy_narg = AS(renameat2_args), .sy_call = (sy_call_t *)sys_renameat2, .sy_auevent = AUE_RENAMEAT, .sy_flags = SYF_CAPENABLED, .sy_thrcnt = SY_THR_STATIC }, /* 602 = renameat2 */
+ { .sy_narg = AS(pdopenpid_args), .sy_call = (sy_call_t *)sys_pdopenpid, .sy_auevent = AUE_PDOPENPID, .sy_flags = 0, .sy_thrcnt = SY_THR_STATIC }, /* 603 = pdopenpid */
};
diff --git a/sys/kern/kern_exit.c b/sys/kern/kern_exit.c
--- a/sys/kern/kern_exit.c
+++ b/sys/kern/kern_exit.c
@@ -1530,8 +1530,8 @@
for (;;) {
/* We own a reference on the procdesc file. */
- KASSERT((pd->pd_flags & PDF_CLOSED) == 0,
- ("PDF_CLOSED proc %p procdesc %p pd flags %#x",
+ KASSERT(pd->pd_fpcount > 0,
+ ("closed proc %p procdesc %p pd flags %#x",
p, pd, pd->pd_flags));
sx_xlock(&proctree_lock);
diff --git a/sys/kern/sys_procdesc.c b/sys/kern/sys_procdesc.c
--- a/sys/kern/sys_procdesc.c
+++ b/sys/kern/sys_procdesc.c
@@ -201,6 +201,29 @@
return (error);
}
+static struct procdesc *
+procdesc_alloc(int flags)
+{
+ struct procdesc *pd;
+
+ pd = malloc(sizeof(*pd), M_PROCDESC, M_WAITOK | M_ZERO);
+ pd->pd_flags = 0;
+ pd->pd_pid = -1;
+ if ((flags & PD_DAEMON) != 0)
+ pd->pd_flags |= PDF_DAEMON;
+ PROCDESC_LOCK_INIT(pd);
+ knlist_init_mtx(&pd->pd_selinfo.si_note, &pd->pd_lock);
+
+ /*
+ * Process descriptors start out with two references: one from their
+ * struct file, and the other from their struct proc.
+ */
+ refcount_init(&pd->pd_refcount, 2);
+ pd->pd_fpcount = 1;
+
+ return (pd);
+}
+
/*
* When a new process is forked by pdfork(), a file descriptor is allocated
* by the fork code first, then the process is forked, and then we get a
@@ -212,21 +235,22 @@
{
struct procdesc *pd;
- pd = malloc(sizeof(*pd), M_PROCDESC, M_WAITOK | M_ZERO);
+ pd = procdesc_alloc(flags);
pd->pd_proc = p;
pd->pd_pid = p->p_pid;
+ MPASS(p->p_procdesc == NULL);
p->p_procdesc = pd;
- pd->pd_flags = 0;
- if (flags & PD_DAEMON)
- pd->pd_flags |= PDF_DAEMON;
- PROCDESC_LOCK_INIT(pd);
- knlist_init_mtx(&pd->pd_selinfo.si_note, &pd->pd_lock);
+}
- /*
- * Process descriptors start out with two references: one from their
- * struct file, and the other from their struct proc.
- */
- refcount_init(&pd->pd_refcount, 2);
+static int
+pdtofdflags(int flags)
+{
+ int fflags;
+
+ fflags = 0;
+ if (flags & PD_CLOEXEC)
+ fflags |= O_CLOEXEC;
+ return (fflags);
}
/*
@@ -236,13 +260,8 @@
procdesc_falloc(struct thread *td, struct file **resultfp, int *resultfd,
int flags, struct filecaps *fcaps)
{
- int fflags;
-
- fflags = 0;
- if (flags & PD_CLOEXEC)
- fflags = O_CLOEXEC;
-
- return (falloc_caps(td, resultfp, resultfd, fflags, fcaps));
+ return (falloc_caps(td, resultfp, resultfd, pdtofdflags(flags),
+ fcaps));
}
/*
@@ -268,8 +287,8 @@
if (refcount_release(&pd->pd_refcount)) {
KASSERT(pd->pd_proc == NULL,
("procdesc_free: pd_proc != NULL"));
- KASSERT((pd->pd_flags & PDF_CLOSED),
- ("procdesc_free: !PDF_CLOSED"));
+ KASSERT(pd->pd_fpcount == 0,
+ ("procdesc_free: not closed %p %d", pd, pd->pd_fpcount));
if (pd->pd_pid != -1)
proc_id_clear(PROC_ID_PID, pd->pd_pid);
@@ -298,7 +317,7 @@
pd = p->p_procdesc;
PROCDESC_LOCK(pd);
- KASSERT((pd->pd_flags & PDF_CLOSED) == 0 || p->p_pptr == p->p_reaper,
+ KASSERT(pd->pd_fpcount > 0 || p->p_pptr == p->p_reaper,
("procdesc_exit: closed && parent not reaper"));
pd->pd_flags |= PDF_EXITED;
@@ -310,7 +329,7 @@
* Clean up the procdesc now rather than letting it happen during
* that reap.
*/
- if (pd->pd_flags & PDF_CLOSED) {
+ if (pd->pd_fpcount == 0) {
PROCDESC_UNLOCK(pd);
pd->pd_proc = NULL;
p->p_procdesc = NULL;
@@ -364,7 +383,8 @@
sx_xlock(&proctree_lock);
PROCDESC_LOCK(pd);
- pd->pd_flags |= PDF_CLOSED;
+ MPASS(pd->pd_fpcount > 0);
+ pd->pd_fpcount--;
PROCDESC_UNLOCK(pd);
p = pd->pd_proc;
if (p == NULL) {
@@ -572,3 +592,70 @@
pdp2 = fp2->f_data;
return (kcmp_cmp((uintptr_t)pdp1->pd_pid, (uintptr_t)pdp2->pd_pid));
}
+
+static int
+kern_pdopenpid(struct thread *td, pid_t pid, int flags)
+{
+ struct file *fp;
+ struct proc *p;
+ struct procdesc *pd, *pdf;
+ int error, fd, fflags;
+
+ fflags = pdtofdflags(flags);
+
+ pdf = procdesc_alloc(flags);
+ error = falloc_noinstall(td, &fp);
+ if (error != 0)
+ goto out2;
+
+ error = pget(pid, PGET_NOTID | PGET_CANDEBUG, &p);
+ if (error != 0)
+ goto out2;
+ if ((p->p_flag & P_WEXIT) != 0) {
+ PROC_UNLOCK(p);
+ error = EBUSY;
+ goto out2;
+ }
+ pd = p->p_procdesc;
+ if (pd != NULL) {
+ refcount_acquire(&pd->pd_refcount);
+ PROCDESC_LOCK(pd);
+ pd->pd_fpcount++;
+ PROCDESC_UNLOCK(pd);
+ refcount_release(&pdf->pd_refcount);
+ } else {
+ pd = pdf;
+ pdf = NULL;
+ pd->pd_proc = p;
+ pd->pd_pid = p->p_pid;
+ p->p_procdesc = pd;
+ procdesc_finit(pd, fp);
+ }
+ PROC_UNLOCK(p);
+
+ error = finstall(td, fp, &fd, fflags, NULL);
+ if (error != 0)
+ goto out1;
+ fdrop(fp, td);
+ td->td_retval[0] = fd;
+ return (0);
+out2:
+ if (pdf != NULL)
+ refcount_release(&pdf->pd_refcount);
+out1:
+ fdrop(fp, td);
+ if (pdf != NULL)
+ procdesc_free(pdf);
+ return (error);
+}
+
+int
+sys_pdopenpid(struct thread *td, struct pdopenpid_args *args)
+{
+ AUDIT_ARG_PID(args->pid);
+ AUDIT_ARG_FFLAGS(args->flags);
+
+ if ((args->flags & ~(PD_ALLOWED_AT_FORK)) != 0)
+ return (EINVAL);
+ return (kern_pdopenpid(td, args->pid, args->flags));
+}
diff --git a/sys/kern/syscalls.c b/sys/kern/syscalls.c
--- a/sys/kern/syscalls.c
+++ b/sys/kern/syscalls.c
@@ -608,4 +608,5 @@
"pdrfork", /* 600 = pdrfork */
"pdwait", /* 601 = pdwait */
"renameat2", /* 602 = renameat2 */
+ "pdopenpid", /* 603 = pdopenpid */
};
diff --git a/sys/kern/syscalls.master b/sys/kern/syscalls.master
--- a/sys/kern/syscalls.master
+++ b/sys/kern/syscalls.master
@@ -3429,4 +3429,11 @@
int flags
);
}
+603 AUE_PDOPENPID STD {
+ int pdopenpid(
+ pid_t pid,
+ int flags
+ );
+ }
+
; 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
@@ -3555,6 +3555,14 @@
*n_args = 5;
break;
}
+ /* pdopenpid */
+ case 603: {
+ struct pdopenpid_args *p = params;
+ iarg[a++] = p->pid; /* pid_t */
+ iarg[a++] = p->flags; /* int */
+ *n_args = 2;
+ break;
+ }
default:
*n_args = 0;
break;
@@ -9521,6 +9529,19 @@
break;
};
break;
+ /* pdopenpid */
+ case 603:
+ switch (ndx) {
+ case 0:
+ p = "pid_t";
+ break;
+ case 1:
+ p = "int";
+ break;
+ default:
+ break;
+ };
+ break;
default:
break;
};
@@ -11549,6 +11570,11 @@
if (ndx == 0 || ndx == 1)
p = "int";
break;
+ /* pdopenpid */
+ case 603:
+ 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
@@ -1412,6 +1412,16 @@
kau_write(rec, tok);
}
break;
+ case AUE_PDOPENPID:
+ if (ARG_IS_VALID(kar, ARG_PID)) {
+ tok = au_to_arg32(0, "PID", ar->ar_arg_pid);
+ kau_write(rec, tok);
+ }
+ if (ARG_IS_VALID(kar, ARG_FLAGS)) {
+ tok = au_to_arg32(2, "flags", ar->ar_arg_flags);
+ kau_write(rec, tok);
+ }
+ break;
case AUE_PROCCTL:
if (ARG_IS_VALID(kar, ARG_VALUE)) {
diff --git a/sys/sys/procdesc.h b/sys/sys/procdesc.h
--- a/sys/sys/procdesc.h
+++ b/sys/sys/procdesc.h
@@ -63,6 +63,7 @@
struct proc *pd_proc; /* (t) Process. */
pid_t pd_pid; /* (c) Cached pid. */
u_int pd_refcount; /* (r) Reference count. */
+ u_int pd_fpcount; /* (p) files referencing me */
/*
* In-flight data and notification of events.
@@ -85,7 +86,6 @@
/*
* Flags for the pd_flags field.
*/
-#define PDF_CLOSED 0x00000001 /* Descriptor has closed. */
#define PDF_EXITED 0x00000004 /* Process exited. */
#define PDF_DAEMON 0x00000008 /* Don't exit when procdesc closes. */
@@ -128,6 +128,7 @@
pid_t pdrfork(int *, int, int);
int pdkill(int, int);
int pdgetpid(int, pid_t *);
+int pdopenpid(pid_t, int);
int pdwait(int, int *, int, struct __wrusage *, struct __siginfo *);
pid_t pdrfork_thread(int *, int, int, void *, int (*)(void *), void *);
__END_DECLS
diff --git a/sys/sys/syscall.h b/sys/sys/syscall.h
--- a/sys/sys/syscall.h
+++ b/sys/sys/syscall.h
@@ -541,4 +541,5 @@
#define SYS_pdrfork 600
#define SYS_pdwait 601
#define SYS_renameat2 602
-#define SYS_MAXSYSCALL 603
+#define SYS_pdopenpid 603
+#define SYS_MAXSYSCALL 604
diff --git a/sys/sys/syscall.mk b/sys/sys/syscall.mk
--- a/sys/sys/syscall.mk
+++ b/sys/sys/syscall.mk
@@ -444,4 +444,5 @@
kexec_load.o \
pdrfork.o \
pdwait.o \
- renameat2.o
+ renameat2.o \
+ pdopenpid.o
diff --git a/sys/sys/sysproto.h b/sys/sys/sysproto.h
--- a/sys/sys/sysproto.h
+++ b/sys/sys/sysproto.h
@@ -1932,6 +1932,10 @@
char new_l_[PADL_(const char *)]; const char * new; char new_r_[PADR_(const char *)];
char flags_l_[PADL_(int)]; int flags; char flags_r_[PADR_(int)];
};
+struct pdopenpid_args {
+ char pid_l_[PADL_(pid_t)]; pid_t pid; char pid_r_[PADR_(pid_t)];
+ char flags_l_[PADL_(int)]; int flags; char flags_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 *);
@@ -2342,6 +2346,7 @@
int sys_pdrfork(struct thread *, struct pdrfork_args *);
int sys_pdwait(struct thread *, struct pdwait_args *);
int sys_renameat2(struct thread *, struct renameat2_args *);
+int sys_pdopenpid(struct thread *, struct pdopenpid_args *);
#ifdef COMPAT_43
@@ -3344,6 +3349,7 @@
#define SYS_AUE_pdrfork AUE_PDRFORK
#define SYS_AUE_pdwait AUE_PDWAIT
#define SYS_AUE_renameat2 AUE_RENAMEAT
+#define SYS_AUE_pdopenpid AUE_PDOPENPID
#undef PAD_
#undef PADL_

File Metadata

Mime Type
text/plain
Expires
Sun, Jul 19, 4:19 PM (8 h, 17 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
35240019
Default Alt Text
D57124.id178293.diff (14 KB)

Event Timeline