Page MenuHomeFreeBSD

D57124.id179251.diff
No OneTemporary

D57124.id179251.diff

diff --git a/lib/libsys/Makefile.sys b/lib/libsys/Makefile.sys
--- a/lib/libsys/Makefile.sys
+++ b/lib/libsys/Makefile.sys
@@ -497,6 +497,7 @@
MLINKS+=pathconf.2 fpathconf.2
MLINKS+=pathconf.2 lpathconf.2
MLINKS+=pdfork.2 pdgetpid.2 \
+ pdfork.2 pdopenpid.2 \
pdfork.2 pdkill.2 \
pdfork.2 pdrfork.2 \
pdfork.2 pdwait.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
@@ -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/pdfork.2 b/lib/libsys/pdfork.2
--- a/lib/libsys/pdfork.2
+++ b/lib/libsys/pdfork.2
@@ -36,6 +36,7 @@
.Sh NAME
.Nm pdfork ,
.Nm pdrfork ,
+.Nm pdopenpid ,
.Nm pdgetpid ,
.Nm pdkill ,
.Nm pdwait
@@ -49,6 +50,8 @@
.Ft pid_t
.Fn pdrfork "int *fdp" "int pdflags" "int rfflags"
.Ft int
+.Fn pdopenpid "pid_t pid" "int pdflags"
+.Ft int
.Fn pdgetpid "int fd" "pid_t *pidp"
.Ft int
.Fn pdkill "int fd" "int signum"
@@ -87,8 +90,7 @@
.Xr capsicum 4
capability mode (see
.Xr cap_enter 2 ) .
-.El
-.Bl -tag -width ".Dv PD_DAEMON"
+The option is effective for the process descriptor returned by the operation.
.It Dv PD_CLOEXEC
Set close-on-exec on process descriptor.
.El
@@ -122,6 +124,28 @@
.Va RFSPAWN
flag are specified.
.Pp
+.Fn pdopenpid
+opens the process descriptor for the process specified by the argument
+.Fa pid .
+It takes the same flags in the
+.Fa pdflags
+argument as
+.Fn pdfork .
+Caller must be allowed to debug the target process for the
+.Fn pdopenpid
+to success.
+Zombie processes cannot be opened.
+.Pp
+There might be more that one file descriptor referencing the process.
+But only one caller of
+.Fn pdwait
+gets the exit status.
+After the zombie is reaped, calls to
+.Fn pdwait
+specifying any file descriptors for the same process fail with the
+.Er ESRCH
+error.
+.Pp
.Fn pdgetpid
queries the process ID (PID) in the process descriptor
.Fa fd .
@@ -192,6 +216,7 @@
.Xr fork 2
does.
.Pp
+.Fn pdopenpid ,
.Fn pdgetpid ,
.Fn pdkill ,
and
@@ -232,6 +257,36 @@
.Dv CAP_PDKILL
for
.Fn pdkill ) .
+.It Bq Er EINVAL
+The
+.Fn pdwait
+function is called with reserved bits set in
+.Fa options .
+.El
+.Pp
+The
+.Fn pdopenpid
+might return the same errors as
+.Xr open 2 ,
+related to the file descriptor allocation problems, as well as the
+following specific errors:
+.Bl -tag -width Er
+.It Bq Er EINVAL
+The
+.Fa flags
+argument has reserved bits set.
+.It Bq Er ENOTCAPABLE
+.Fn pdopenpid
+is called by the process in capability mode.
+.It Bq Er EBUSY
+The process specified by the
+.Fa pid
+argument already terminated.
+.It Bq Er ESRCH
+The process specified by the
+.Fa pid
+argument does not exist, or the caller does not have enough privileges
+to open the process.
.El
.Sh SEE ALSO
.Xr close 2 ,
@@ -257,6 +312,10 @@
.Fn pdwait
system calls first appeared in
.Fx 15.1 .
+The
+.Fn pdopenpid
+system call first appeared in
+.Fx 16.0 .
.Pp
Support for process descriptors mode was developed as part of the
.Tn TrustedBSD
@@ -277,3 +336,7 @@
.An Konstantin Belousov Aq Mt kib@FreeBSD.org
with input from
.An Alan Somers Aq Mt asomers@FreeBSD.org .
+The
+.Fn pdopenpid
+function was developed by
+.An Konstantin Belousov Aq Mt kib@FreeBSD.org .
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,27 @@
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;
+ 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 +233,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 +258,12 @@
procdesc_falloc(struct thread *td, struct file **resultfp, int *resultfd,
int flags, struct filecaps *fcaps)
{
- int fflags;
+ int error;
- fflags = 0;
- if (flags & PD_CLOEXEC)
- fflags = O_CLOEXEC;
-
- return (falloc_caps(td, resultfp, resultfd, fflags, fcaps));
+ error = falloc_caps(td, resultfp, resultfd, pdtofdflags(flags), fcaps);
+ if (error == 0 && (flags & PD_DAEMON) != 0)
+ (*resultfp)->f_pdflags |= F_PD_NOKILL;
+ return (error);
}
/*
@@ -255,6 +276,14 @@
finit(fp, FREAD | FWRITE, DTYPE_PROCDESC, pdp, &procdesc_ops);
}
+static void
+procdesc_destroy(struct procdesc *pd)
+{
+ knlist_destroy(&pd->pd_selinfo.si_note);
+ PROCDESC_LOCK_DESTROY(pd);
+ free(pd, M_PROCDESC);
+}
+
static void
procdesc_free(struct procdesc *pd)
{
@@ -268,16 +297,14 @@
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);
seldrain(&pd->pd_selinfo);
- knlist_destroy(&pd->pd_selinfo.si_note);
- PROCDESC_LOCK_DESTROY(pd);
- free(pd, M_PROCDESC);
+ procdesc_destroy(pd);
}
}
@@ -294,11 +321,12 @@
sx_assert(&proctree_lock, SA_XLOCKED);
PROC_LOCK_ASSERT(p, MA_OWNED);
KASSERT(p->p_procdesc != NULL, ("procdesc_exit: p_procdesc NULL"));
+ MPASS((p->p_flag & P_WEXIT) != 0);
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 +338,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;
@@ -344,6 +372,15 @@
procdesc_free(pd);
}
+static void
+procdesc_close_tail(struct file *fp, struct proc *p)
+{
+ if ((fp->f_pdflags & F_PD_NOKILL) == 0)
+ kern_psignal(p, SIGKILL);
+ PROC_UNLOCK(p);
+ sx_xunlock(&proctree_lock);
+}
+
/*
* procdesc_close() - last close on a process descriptor. If the process is
* still running, terminate with SIGKILL (unless PDF_DAEMON is set) and let
@@ -364,7 +401,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) {
@@ -384,7 +422,7 @@
* calls back into procdesc_reap().
*/
proc_reap(curthread, p, NULL, 0);
- } else {
+ } else if (pd->pd_fpcount == 0) /* last procdesc */ {
/*
* If the process is not yet dead, we need to kill it,
* but we can't wait around synchronously for it to go
@@ -410,10 +448,9 @@
p->p_oppid = p->p_reaper->p_pid;
proc_add_orphan(p, p->p_reaper);
}
- if ((pd->pd_flags & PDF_DAEMON) == 0)
- kern_psignal(p, SIGKILL);
- PROC_UNLOCK(p);
- sx_xunlock(&proctree_lock);
+ procdesc_close_tail(fp, p);
+ } else {
+ procdesc_close_tail(fp, p);
}
}
@@ -572,3 +609,92 @@
pdp2 = fp2->f_data;
return (kcmp_cmp((uintptr_t)pdp1->pd_pid, (uintptr_t)pdp2->pd_pid));
}
+
+static int
+pdopenpid1(struct thread *td, pid_t pid, struct procdesc **pdf, struct file *fp)
+{
+ struct proc *p;
+ struct procdesc *pd;
+ int error;
+
+ sx_assert(&proctree_lock, SX_XLOCKED);
+
+ error = pget(pid, PGET_NOTID | PGET_CANDEBUG, &p);
+ if (error != 0)
+ return (error);
+ if ((p->p_flag & (P_SYSTEM | P_WEXIT)) != 0) {
+ PROC_UNLOCK(p);
+ return (EBUSY);
+ }
+ pd = p->p_procdesc;
+ if (pd != NULL) {
+ refcount_acquire(&pd->pd_refcount);
+ PROCDESC_LOCK(pd);
+ MPASS(pd->pd_fpcount > 0);
+ pd->pd_fpcount++;
+ PROCDESC_UNLOCK(pd);
+ } 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);
+ return (0);
+}
+
+static int
+kern_pdopenpid(struct thread *td, pid_t pid, int flags)
+{
+ struct file *fp;
+ struct procdesc *pdf;
+ int error, fd, fflags;
+
+ error = falloc_noinstall(td, &fp);
+ if (error != 0)
+ return (error);
+ fflags = pdtofdflags(flags);
+ pdf = procdesc_alloc(flags);
+ if ((flags & PD_DAEMON) != 0)
+ fp->f_pdflags |= F_PD_NOKILL;
+
+ sx_xlock(&proctree_lock);
+ error = pdopenpid1(td, pid, &pdf, fp);
+ sx_xunlock(&proctree_lock);
+
+ if (error == 0) {
+ error = finstall(td, fp, &fd, fflags, NULL);
+ if (error == 0) {
+ td->td_retval[0] = fd;
+ } else {
+ /*
+ * Not killing the target process if cannot
+ * return filedescriptor to userspace.
+ */
+ fp->f_pdflags |= F_PD_NOKILL;
+ }
+ }
+ fdrop(fp, td);
+
+ if (pdf != NULL) {
+ MPASS(pdf->pd_refcount == 2);
+ MPASS(pdf->pd_fpcount == 1);
+ MPASS(pdf->pd_proc == NULL);
+ MPASS(pdf->pd_pid == -1);
+ procdesc_destroy(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(1, "PID", ar->ar_arg_pid);
+ kau_write(rec, tok);
+ }
+ if (ARG_IS_VALID(kar, ARG_FFLAGS)) {
+ tok = au_to_arg32(2, "flags", ar->ar_arg_fflags);
+ kau_write(rec, tok);
+ }
+ break;
case AUE_PROCCTL:
if (ARG_IS_VALID(kar, ARG_VALUE)) {
diff --git a/sys/sys/file.h b/sys/sys/file.h
--- a/sys/sys/file.h
+++ b/sys/sys/file.h
@@ -213,6 +213,7 @@
union {
int16_t f_seqcount[2]; /* (a) Count of seq. reads and writes. */
int f_pipegen;
+ int f_pdflags; /* Per-file flags for procdesc. */
};
off_t f_nextoff[2]; /* next expected read/write offset. */
union {
diff --git a/sys/sys/procdesc.h b/sys/sys/procdesc.h
--- a/sys/sys/procdesc.h
+++ b/sys/sys/procdesc.h
@@ -51,6 +51,8 @@
* (r) - Atomic reference count.
* (s) - Protected by selinfo.
* (t) - Protected by the proctree_lock
+ * (p|t) - Both procree_lock and process descriptor must be locked
+ * for pd_fpcount
*/
struct proc;
struct sigio;
@@ -63,6 +65,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|t) files referencing me */
/*
* In-flight data and notification of events.
@@ -85,9 +88,13 @@
/*
* 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. */
+
+/*
+ * Flags for file f_pdflags.
+ */
+#define F_PD_NOKILL 0x00000001 /* Opened with PD_DAEMON. Don't send
+ SIGKILL when file closes. */
/*
* In-kernel interfaces to process descriptors.
@@ -128,6 +135,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
Thu, Jun 25, 5:07 PM (12 h, 50 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
34325649
Default Alt Text
D57124.id179251.diff (20 KB)

Event Timeline