Page MenuHomeFreeBSD

D58117.id181575.diff
No OneTemporary

D58117.id181575.diff

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
@@ -173,16 +173,11 @@
struct file *fp;
int error;
- error = fget(td, fd, rightsp, &fp);
- if (error)
- return (error);
- if (fp->f_type != DTYPE_PROCDESC) {
- error = EBADF;
- goto out;
+ error = fget_procdesc(td, fd, rightsp, &fp, NULL, NULL);
+ if (error == 0) {
+ *pidp = procdesc_pid(fp);
+ fdrop(fp, td);
}
- *pidp = procdesc_pid(fp);
-out:
- fdrop(fp, td);
return (error);
}
@@ -704,44 +699,73 @@
return (kern_pdopenpid(td, args->pid, args->flags));
}
+int
+fget_procdesc(struct thread *td, int pdfd, const cap_rights_t *cap_rights,
+ struct file **pfp, struct procdesc **pdp, struct proc **pp)
+{
+ struct file *fp;
+ struct procdesc *pd;
+ struct proc *p;
+ int error;
+
+ if (pp != NULL)
+ sx_assert(&proctree_lock, SX_LOCKED);
+
+ error = fget(td, pdfd, cap_rights, &fp);
+ if (error != 0)
+ return (error);
+ if (fp->f_type != DTYPE_PROCDESC) {
+ fdrop(fp, td);
+ return (EBADF);
+ }
+ pd = fp->f_data;
+ if (pp != NULL) {
+ p = pd->pd_proc;
+ if (p == NULL) {
+ fdrop(fp, td);
+ return (ESRCH);
+ } else {
+ PROC_LOCK(p);
+ *pp = p;
+ }
+ }
+ *pfp = fp;
+ if (pdp != NULL)
+ *pdp = pd;
+ return (0);
+}
+
static int
kern_pddupfd(struct thread *td, int pdfd, int fd, int flags)
{
struct proc *p;
struct file *fp, *pfp;
- struct procdesc *pd;
struct filecaps fcaps;
uint8_t fd_flags;
int error, fdr;
- error = fget(td, pdfd, &cap_pddupfd_rights, &pfp);
+ sx_slock(&proctree_lock);
+ error = fget_procdesc(td, pdfd, &cap_pddupfd_rights, &pfp, NULL, &p);
+ sx_sunlock(&proctree_lock);
if (error != 0)
return (error);
- if (pfp->f_type != DTYPE_PROCDESC) {
- error = EBADF;
- goto out;
- }
- pd = pfp->f_data;
-again:
- sx_slock(&proctree_lock);
- p = pd->pd_proc;
- if (p != NULL) {
- AUDIT_ARG_PROCESS(p);
- PROC_LOCK(p);
- sx_sunlock(&proctree_lock);
+ AUDIT_ARG_PROCESS(p);
+ for (;;) {
+ PROC_LOCK_ASSERT(p, MA_OWNED);
if ((p->p_flag & P_WEXIT) != 0) {
error = ESRCH;
} else {
/*
- * Block the target process from entering
- * execve(). We need to ensure that the
- * p_candebug() predicate is stable until the
- * fget_remote() call ends even after the
- * process lock is dropped. For that, the
+ * Block the target process from entering execve().
+ * We need to ensure that the p_candebug() predicate
+ * is stable until the fget_remote() call ends even
+ * after the process lock is dropped. For that, the
* process must not change uid/suid.
*/
- if (!execve_block(td, p))
- goto again;
+ if (!execve_block(td, p)) {
+ PROC_LOCK(p);
+ continue;
+ }
error = p_candebug(td, p);
if (error == 0)
_PHOLD(p);
@@ -749,9 +773,9 @@
execve_unblock(td, p);
}
PROC_UNLOCK(p);
- if (error != 0)
- goto out;
-
+ break;
+ }
+ if (error == 0) {
error = fget_remote(td, p, fd, &fcaps, &fd_flags, &fp);
PROC_LOCK(p);
execve_unblock(td, p);
@@ -768,11 +792,7 @@
td->td_retval[0] = fdr;
}
}
- } else {
- sx_sunlock(&proctree_lock);
- error = ESRCH;
}
-out:
fdrop(pfp, td);
return (error);
}
diff --git a/sys/sys/procdesc.h b/sys/sys/procdesc.h
--- a/sys/sys/procdesc.h
+++ b/sys/sys/procdesc.h
@@ -113,7 +113,9 @@
int procdesc_falloc(struct thread *, struct file **, int *, int,
struct filecaps *);
-
+int fget_procdesc(struct thread *td, int pfd,
+ const cap_rights_t *cap_rights, struct file **pfp,
+ struct procdesc **pdp, struct proc **pp);
#else /* !_KERNEL */
#include <sys/cdefs.h>

File Metadata

Mime Type
text/plain
Expires
Tue, Sep 1, 4:21 PM (59 m, 49 s)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
37837870
Default Alt Text
D58117.id181575.diff (3 KB)

Event Timeline