Changeset View
Standalone View
sys/kern/kern_proc.c
Show First 20 Lines • Show All 2,961 Lines • ▼ Show 20 Lines | kst.ksigtramp_start = (char *)sv->sv_psstrings - | ||||
*sv->sv_szsigcode; | *sv->sv_szsigcode; | ||||
kst.ksigtramp_end = (char *)sv->sv_psstrings; | kst.ksigtramp_end = (char *)sv->sv_psstrings; | ||||
} | } | ||||
PROC_UNLOCK(p); | PROC_UNLOCK(p); | ||||
error = SYSCTL_OUT(req, &kst, sizeof(kst)); | error = SYSCTL_OUT(req, &kst, sizeof(kst)); | ||||
return (error); | return (error); | ||||
} | } | ||||
static int | |||||
sysctl_kern_proc_fastsigblk(SYSCTL_HANDLER_ARGS) | |||||
{ | |||||
int *name = (int *)arg1; | |||||
u_int namelen = arg2; | |||||
pid_t pid; | |||||
struct proc *p; | |||||
struct thread *td1; | |||||
uintptr_t addr; | |||||
#ifdef COMPAT_FREEBSD32 | |||||
uint32_t addr32; | |||||
#endif | |||||
int error; | |||||
if (namelen != 1 || req->newptr != NULL) | |||||
return (EINVAL); | |||||
pid = (pid_t)name[0]; | |||||
error = pget(pid, PGET_HOLD | PGET_NOTWEXIT | PGET_CANDEBUG, &p); | |||||
if (error != 0) | |||||
return (error); | |||||
PROC_LOCK(p); | |||||
#ifdef COMPAT_FREEBSD32 | |||||
if (SV_CURPROC_FLAG(SV_ILP32)) { | |||||
if (!SV_PROC_FLAG(p, SV_ILP32)) { | |||||
error = EINVAL; | |||||
goto errlocked; | |||||
} | |||||
} | |||||
#endif | |||||
if (pid <= PID_MAX) { | |||||
td1 = FIRST_THREAD_IN_PROC(p); | |||||
} else { | |||||
FOREACH_THREAD_IN_PROC(p, td1) { | |||||
if (td1->td_tid == pid) | |||||
break; | |||||
} | |||||
} | |||||
if (td1 == NULL) { | |||||
error = ESRCH; | |||||
goto errlocked; | |||||
} | |||||
/* | |||||
* The access to the private thread flags. It is fine as far | |||||
* as no out-of-thin-air values are read from td_pflags, and | |||||
* usermode read of the td_sigblock_ptr is racy inherently, | |||||
* since target process might have already changed it | |||||
* meantime. | |||||
*/ | |||||
if ((td1->td_pflags & TDP_FAST_SIGBLOCK) != 0) | |||||
addr = (uintptr_t)td1->td_sigblock_ptr; | |||||
else | |||||
error = ENOTTY; | |||||
errlocked: | |||||
_PRELE(p); | |||||
PROC_UNLOCK(p); | |||||
if (error != 0) | |||||
return (error); | |||||
#ifdef COMPAT_FREEBSD32 | |||||
brooks: Since this sysctl appears to be intended to be diagnostic in nature (rather than being intended… | |||||
Done Inline ActionsThe intent of this syscall is to allow debuggers to get more accurate idea of the process signal mask, In other words, I want this sysctl to be usable by compat32 when target process is also compat32. kib: The intent of this syscall is to allow debuggers to get more accurate idea of the process… | |||||
Not Done Inline ActionsI don't see how using kvaddr_t prevents that usage. I'd think that at most we'd talking about one cast in some OS dependent code. This code also don't match the usage in procstat where a reference to a uintmax_t is used. It might work by accident on i386, but it's going to be nonsense on 32-bit BE systems. brooks: I don't see how using kvaddr_t prevents that usage. I'd think that at most we'd talking about… | |||||
Done Inline Actionskvaddr_t is 64bit on LP64, which means that compat32 code call would end up with kernel doing SYSCTL_OUT() 64bit value over 32bit length out argument. This should result in ENOMEM. I will fix procstat, it arguably requires more substantial changes, it is not very useful to repeat the address for each signal number. I will add a new subcommand to procstat. kib: kvaddr_t is 64bit on LP64, which means that compat32 code call would end up with kernel doing… | |||||
if (SV_CURPROC_FLAG(SV_ILP32)) { | |||||
addr32 = addr; | |||||
error = SYSCTL_OUT(req, &addr32, sizeof(addr32)); | |||||
} else | |||||
#endif | |||||
error = SYSCTL_OUT(req, &addr, sizeof(addr)); | |||||
return (error); | |||||
} | |||||
SYSCTL_NODE(_kern, KERN_PROC, proc, CTLFLAG_RD, 0, "Process table"); | SYSCTL_NODE(_kern, KERN_PROC, proc, CTLFLAG_RD, 0, "Process table"); | ||||
SYSCTL_PROC(_kern_proc, KERN_PROC_ALL, all, CTLFLAG_RD|CTLTYPE_STRUCT| | SYSCTL_PROC(_kern_proc, KERN_PROC_ALL, all, CTLFLAG_RD|CTLTYPE_STRUCT| | ||||
CTLFLAG_MPSAFE, 0, 0, sysctl_kern_proc, "S,proc", | CTLFLAG_MPSAFE, 0, 0, sysctl_kern_proc, "S,proc", | ||||
"Return entire process table"); | "Return entire process table"); | ||||
static SYSCTL_NODE(_kern_proc, KERN_PROC_GID, gid, CTLFLAG_RD | CTLFLAG_MPSAFE, | static SYSCTL_NODE(_kern_proc, KERN_PROC_GID, gid, CTLFLAG_RD | CTLFLAG_MPSAFE, | ||||
sysctl_kern_proc, "Process table"); | sysctl_kern_proc, "Process table"); | ||||
▲ Show 20 Lines • Show All 96 Lines • ▼ Show 20 Lines | |||||
static SYSCTL_NODE(_kern_proc, KERN_PROC_OSREL, osrel, CTLFLAG_RW | | static SYSCTL_NODE(_kern_proc, KERN_PROC_OSREL, osrel, CTLFLAG_RW | | ||||
CTLFLAG_ANYBODY | CTLFLAG_MPSAFE, sysctl_kern_proc_osrel, | CTLFLAG_ANYBODY | CTLFLAG_MPSAFE, sysctl_kern_proc_osrel, | ||||
"Process binary osreldate"); | "Process binary osreldate"); | ||||
static SYSCTL_NODE(_kern_proc, KERN_PROC_SIGTRAMP, sigtramp, CTLFLAG_RD | | static SYSCTL_NODE(_kern_proc, KERN_PROC_SIGTRAMP, sigtramp, CTLFLAG_RD | | ||||
CTLFLAG_MPSAFE, sysctl_kern_proc_sigtramp, | CTLFLAG_MPSAFE, sysctl_kern_proc_sigtramp, | ||||
"Process signal trampoline location"); | "Process signal trampoline location"); | ||||
static SYSCTL_NODE(_kern_proc, KERN_PROC_FASTSIGBLK, fastsigblk, CTLFLAG_RD | | |||||
CTLFLAG_ANYBODY | CTLFLAG_MPSAFE, sysctl_kern_proc_fastsigblk, | |||||
"Thread fast_sigblock address"); | |||||
int allproc_gen; | int allproc_gen; | ||||
/* | /* | ||||
* stop_all_proc() purpose is to stop all process which have usermode, | * stop_all_proc() purpose is to stop all process which have usermode, | ||||
* except current process for obvious reasons. This makes it somewhat | * except current process for obvious reasons. This makes it somewhat | ||||
* unreliable when invoked from multithreaded process. The service | * unreliable when invoked from multithreaded process. The service | ||||
* must not be user-callable anyway. | * must not be user-callable anyway. | ||||
▲ Show 20 Lines • Show All 132 Lines • Show Last 20 Lines |
Since this sysctl appears to be intended to be diagnostic in nature (rather than being intended to return a pointer that is used as such), I wonder if it would make sense to export a kvaddr_t to avoid the need for COMPAT code.