Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F169229335
D58117.id181604.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
5 KB
Referenced Files
None
Subscribers
None
D58117.id181604.diff
View Options
diff --git a/sys/kern/kern_sig.c b/sys/kern/kern_sig.c
--- a/sys/kern/kern_sig.c
+++ b/sys/kern/kern_sig.c
@@ -1956,6 +1956,7 @@
sys_pdkill(struct thread *td, struct pdkill_args *uap)
{
struct proc *p;
+ struct file *fp;
int error;
AUDIT_ARG_SIGNUM(uap->signum);
@@ -1963,14 +1964,17 @@
if ((u_int)uap->signum > _SIG_MAXSIG)
return (EINVAL);
- error = procdesc_find(td, uap->fd, &cap_pdkill_rights, &p);
- if (error)
+ sx_slock(&proctree_lock);
+ error = fget_procdesc(td, uap->fd, &cap_pdkill_rights, &fp, NULL, &p);
+ sx_sunlock(&proctree_lock);
+ if (error != 0)
return (error);
AUDIT_ARG_PROCESS(p);
error = p_cansignal(td, p, uap->signum);
- if (error == 0 && uap->signum)
+ if (error == 0 && uap->signum != 0)
kern_psignal(p, uap->signum);
PROC_UNLOCK(p);
+ fdrop(fp, td);
return (error);
}
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
@@ -115,38 +115,6 @@
.fo_flags = DFLAG_PASSABLE,
};
-/*
- * Return a locked process given a process descriptor, or ESRCH if it has
- * died.
- */
-int
-procdesc_find(struct thread *td, int fd, const cap_rights_t *rightsp,
- struct proc **p)
-{
- struct procdesc *pd;
- struct file *fp;
- int error;
-
- error = fget(td, fd, rightsp, &fp);
- if (error)
- return (error);
- if (fp->f_type != DTYPE_PROCDESC) {
- error = EINVAL;
- goto out;
- }
- pd = fp->f_data;
- sx_slock(&proctree_lock);
- if (pd->pd_proc != NULL) {
- *p = pd->pd_proc;
- PROC_LOCK(*p);
- } else
- error = ESRCH;
- sx_sunlock(&proctree_lock);
-out:
- fdrop(fp, td);
- return (error);
-}
-
/*
* Function to be used by procstat(1) sysctls when returning procdesc
* information.
@@ -173,16 +141,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 +667,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 +741,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 +760,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
@@ -102,8 +102,6 @@
* In-kernel interfaces to process descriptors.
*/
int procdesc_exit(struct proc *);
-int procdesc_find(struct thread *, int fd, const cap_rights_t *,
- struct proc **);
int kern_pdgetpid(struct thread *, int fd, const cap_rights_t *,
pid_t *pidp);
void procdesc_new(struct proc *, int);
@@ -113,7 +111,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
Details
Attached
Mime Type
text/plain
Expires
Tue, Sep 1, 11:25 PM (7 h, 29 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
37862258
Default Alt Text
D58117.id181604.diff (5 KB)
Attached To
Mode
D58117: kern: add fget_procdesc()
Attached
Detach File
Event Timeline
Log In to Comment