mirror of
https://git.FreeBSD.org/src.git
synced 2024-12-13 10:02:38 +00:00
- Change fill_kinfo_proc() to require that the process is locked when it
is called. - Change sysctl_out_proc() to require that the process is locked when it is called and to drop the lock before it returns. If this proves too complex we can change sysctl_out_proc() to simply acquire the lock at the very end and have the calling code drop the lock right after it returns. - Lock the process we are going to export before the p_cansee() in the loop in sysctl_kern_proc() and hold the lock until we call sysctl_out_proc(). - Don't call p_cansee() on the process about to be exported twice in the aforementioned loop.
This commit is contained in:
parent
ad278afdf0
commit
65c9b4303b
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=94307
@ -489,12 +489,12 @@ linprocfs_doprocstat(PFS_FILL_ARGS)
|
||||
{
|
||||
struct kinfo_proc kp;
|
||||
|
||||
PROC_LOCK(p);
|
||||
fill_kinfo_proc(p, &kp);
|
||||
sbuf_printf(sb, "%d", p->p_pid);
|
||||
#define PS_ADD(name, fmt, arg) sbuf_printf(sb, " " fmt, arg)
|
||||
PS_ADD("comm", "(%s)", p->p_comm);
|
||||
PS_ADD("statr", "%c", '0'); /* XXX */
|
||||
PROC_LOCK(p);
|
||||
PS_ADD("ppid", "%d", p->p_pptr ? p->p_pptr->p_pid : 0);
|
||||
PS_ADD("pgrp", "%d", p->p_pgid);
|
||||
PS_ADD("session", "%d", p->p_session->s_sid);
|
||||
@ -571,6 +571,7 @@ linprocfs_doprocstatus(PFS_FILL_ARGS)
|
||||
state = state_str[(int)p->p_stat];
|
||||
mtx_unlock_spin(&sched_lock);
|
||||
|
||||
PROC_LOCK(p);
|
||||
fill_kinfo_proc(p, &kp);
|
||||
sbuf_printf(sb, "Name:\t%s\n", p->p_comm); /* XXX escape */
|
||||
sbuf_printf(sb, "State:\t%s\n", state);
|
||||
@ -579,7 +580,6 @@ linprocfs_doprocstatus(PFS_FILL_ARGS)
|
||||
* Credentials
|
||||
*/
|
||||
sbuf_printf(sb, "Pid:\t%d\n", p->p_pid);
|
||||
PROC_LOCK(p);
|
||||
sbuf_printf(sb, "PPid:\t%d\n", p->p_pptr ?
|
||||
p->p_pptr->p_pid : 0);
|
||||
sbuf_printf(sb, "Uid:\t%d %d %d %d\n", p->p_ucred->cr_ruid,
|
||||
|
@ -163,7 +163,8 @@ pecoff_coredump(register struct thread * td, register struct vnode * vp,
|
||||
off_t limit)
|
||||
{
|
||||
register struct ucred *cred = td->td_ucred;
|
||||
register struct vmspace *vm = td->td_proc->p_vmspace;
|
||||
struct proc *p = td->td_proc;
|
||||
register struct vmspace *vm = p->p_vmspace;
|
||||
int error;
|
||||
#ifdef PECOFF_DEBUG
|
||||
struct vm_map *map;
|
||||
@ -173,7 +174,9 @@ pecoff_coredump(register struct thread * td, register struct vnode * vp,
|
||||
#endif
|
||||
if (ctob((UAREA_PAGES+KSTACK_PAGES) + vm->vm_dsize + vm->vm_ssize) >= limit)
|
||||
return (EFAULT);
|
||||
fill_kinfo_proc(td->td_proc, &td->td_proc->p_uarea->u_kproc);
|
||||
PROC_LOCK(p);
|
||||
fill_kinfo_proc(p, &p->p_uarea->u_kproc);
|
||||
PROC_UNLOCK(p);
|
||||
|
||||
#if PECOFF_DEBUG
|
||||
fill_regs(td, ®s);
|
||||
|
@ -263,7 +263,9 @@ aout_coredump(td, vp, limit)
|
||||
if (ctob((UAREA_PAGES + KSTACK_PAGES)
|
||||
+ vm->vm_dsize + vm->vm_ssize) >= limit)
|
||||
return (EFAULT);
|
||||
PROC_LOCK(p);
|
||||
fill_kinfo_proc(p, &p->p_uarea->u_kproc);
|
||||
PROC_UNLOCK(p);
|
||||
error = cpu_coredump(td, vp, cred);
|
||||
if (error == 0)
|
||||
error = vn_rdwr(UIO_WRITE, vp, vm->vm_daddr,
|
||||
|
@ -629,6 +629,7 @@ DB_SHOW_COMMAND(pgrpdump, pgrpdump)
|
||||
|
||||
/*
|
||||
* Fill in an kinfo_proc structure for the specified process.
|
||||
* Must be called with the target process locked.
|
||||
*/
|
||||
void
|
||||
fill_kinfo_proc(p, kp)
|
||||
@ -644,7 +645,7 @@ fill_kinfo_proc(p, kp)
|
||||
|
||||
kp->ki_structsize = sizeof(*kp);
|
||||
kp->ki_paddr = p;
|
||||
PROC_LOCK(p);
|
||||
PROC_LOCK_ASSERT(p, MA_OWNED);
|
||||
kp->ki_addr =/* p->p_addr; */0; /* XXXKSE */
|
||||
kp->ki_args = p->p_args;
|
||||
kp->ki_tracep = p->p_tracep;
|
||||
@ -764,7 +765,6 @@ fill_kinfo_proc(p, kp)
|
||||
kp->ki_lock = p->p_lock;
|
||||
if (p->p_pptr)
|
||||
kp->ki_ppid = p->p_pptr->p_pid;
|
||||
PROC_UNLOCK(p);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -786,6 +786,9 @@ zpfind(pid_t pid)
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Must be called with the process locked and will return with it unlocked.
|
||||
*/
|
||||
static int
|
||||
sysctl_out_proc(struct proc *p, struct sysctl_req *req, int doingzomb)
|
||||
{
|
||||
@ -794,7 +797,9 @@ sysctl_out_proc(struct proc *p, struct sysctl_req *req, int doingzomb)
|
||||
struct proc *np;
|
||||
pid_t pid = p->p_pid;
|
||||
|
||||
PROC_LOCK_ASSERT(p, MA_OWNED);
|
||||
fill_kinfo_proc(p, &kinfo_proc);
|
||||
PROC_UNLOCK(p);
|
||||
error = SYSCTL_OUT(req, (caddr_t)&kinfo_proc, sizeof(kinfo_proc));
|
||||
if (error)
|
||||
return (error);
|
||||
@ -834,7 +839,6 @@ sysctl_kern_proc(SYSCTL_HANDLER_ARGS)
|
||||
PROC_UNLOCK(p);
|
||||
return (0);
|
||||
}
|
||||
PROC_UNLOCK(p);
|
||||
error = sysctl_out_proc(p, req, 0);
|
||||
return (error);
|
||||
}
|
||||
@ -858,16 +862,21 @@ sysctl_kern_proc(SYSCTL_HANDLER_ARGS)
|
||||
else
|
||||
p = LIST_FIRST(&zombproc);
|
||||
for (; p != 0; p = LIST_NEXT(p, p_list)) {
|
||||
PROC_LOCK(p);
|
||||
/*
|
||||
* Show a user only appropriate processes.
|
||||
*/
|
||||
if (p_cansee(curproc, p))
|
||||
if (p_cansee(curproc, p)) {
|
||||
PROC_UNLOCK(p);
|
||||
continue;
|
||||
}
|
||||
/*
|
||||
* Skip embryonic processes.
|
||||
*/
|
||||
if (p->p_stat == SIDL)
|
||||
if (p->p_stat == SIDL) {
|
||||
PROC_UNLOCK(p);
|
||||
continue;
|
||||
}
|
||||
/*
|
||||
* TODO - make more efficient (see notes below).
|
||||
* do by session.
|
||||
@ -876,17 +885,14 @@ sysctl_kern_proc(SYSCTL_HANDLER_ARGS)
|
||||
|
||||
case KERN_PROC_PGRP:
|
||||
/* could do this by traversing pgrp */
|
||||
PROC_LOCK(p);
|
||||
if (p->p_pgrp == NULL ||
|
||||
p->p_pgrp->pg_id != (pid_t)name[0]) {
|
||||
PROC_UNLOCK(p);
|
||||
continue;
|
||||
}
|
||||
PROC_UNLOCK(p);
|
||||
break;
|
||||
|
||||
case KERN_PROC_TTY:
|
||||
PROC_LOCK(p);
|
||||
if ((p->p_flag & P_CONTROLT) == 0 ||
|
||||
p->p_session == NULL) {
|
||||
PROC_UNLOCK(p);
|
||||
@ -901,25 +907,25 @@ sysctl_kern_proc(SYSCTL_HANDLER_ARGS)
|
||||
continue;
|
||||
}
|
||||
SESS_UNLOCK(p->p_session);
|
||||
PROC_UNLOCK(p);
|
||||
break;
|
||||
|
||||
case KERN_PROC_UID:
|
||||
if (p->p_ucred == NULL ||
|
||||
p->p_ucred->cr_uid != (uid_t)name[0])
|
||||
p->p_ucred->cr_uid != (uid_t)name[0]) {
|
||||
PROC_UNLOCK(p);
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
|
||||
case KERN_PROC_RUID:
|
||||
if (p->p_ucred == NULL ||
|
||||
p->p_ucred->cr_ruid != (uid_t)name[0])
|
||||
p->p_ucred->cr_ruid != (uid_t)name[0]) {
|
||||
PROC_UNLOCK(p);
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (p_cansee(curproc, p))
|
||||
continue;
|
||||
|
||||
error = sysctl_out_proc(p, req, doingzomb);
|
||||
if (error) {
|
||||
sx_sunlock(&allproc_lock);
|
||||
|
@ -488,7 +488,9 @@ ptrace(struct thread *td, struct ptrace_args *uap)
|
||||
}
|
||||
|
||||
if (uap->addr != (caddr_t)1) {
|
||||
PROC_LOCK(p);
|
||||
fill_kinfo_proc(p, &p->p_uarea->u_kproc);
|
||||
PROC_UNLOCK(p);
|
||||
error = ptrace_set_pc(td2,
|
||||
(u_long)(uintfptr_t)uap->addr);
|
||||
if (error) {
|
||||
|
Loading…
Reference in New Issue
Block a user