aboutsummaryrefslogtreecommitdiff
path: root/sys/kern/kern_proc.c
diff options
context:
space:
mode:
authorKonstantin Belousov <kib@FreeBSD.org>2020-02-09 12:29:51 +0000
committerKonstantin Belousov <kib@FreeBSD.org>2020-02-09 12:29:51 +0000
commit48fcb463114eda4e5d6db9d709d5dbf53465852b (patch)
tree14c7c3e7266008ed6359c947ccbbb13f731aec2c /sys/kern/kern_proc.c
parentfc908e500165fec250bea86310e7ae0eedc23af8 (diff)
downloadsrc-48fcb463114eda4e5d6db9d709d5dbf53465852b.tar.gz
src-48fcb463114eda4e5d6db9d709d5dbf53465852b.zip
Notes
Diffstat (limited to 'sys/kern/kern_proc.c')
-rw-r--r--sys/kern/kern_proc.c75
1 files changed, 75 insertions, 0 deletions
diff --git a/sys/kern/kern_proc.c b/sys/kern/kern_proc.c
index d74295269870..0ff776cf662d 100644
--- a/sys/kern/kern_proc.c
+++ b/sys/kern/kern_proc.c
@@ -2962,6 +2962,77 @@ sysctl_kern_proc_sigtramp(SYSCTL_HANDLER_ARGS)
return (error);
}
+static int
+sysctl_kern_proc_sigfastblk(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_SIGFASTBLOCK) != 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
+ 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_PROC(_kern_proc, KERN_PROC_ALL, all, CTLFLAG_RD|CTLTYPE_STRUCT|
@@ -3075,6 +3146,10 @@ static SYSCTL_NODE(_kern_proc, KERN_PROC_SIGTRAMP, sigtramp, CTLFLAG_RD |
CTLFLAG_MPSAFE, sysctl_kern_proc_sigtramp,
"Process signal trampoline location");
+static SYSCTL_NODE(_kern_proc, KERN_PROC_SIGFASTBLK, sigfastblk, CTLFLAG_RD |
+ CTLFLAG_ANYBODY | CTLFLAG_MPSAFE, sysctl_kern_proc_sigfastblk,
+ "Thread sigfastblock address");
+
int allproc_gen;
/*