From 80c3af4e8051c00b781aeee059bda088f33ade3f Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Tue, 26 Nov 2013 19:47:09 +0000 Subject: [PATCH] Add an kinfo sysctl to retrieve signal trampoline location for the given process. Note that the correctness of the trampoline length returned for ABIs which do not use shared page depends on the correctness of the struct sysvec sv_szsigcodebase member, which will be fixed on as-need basis. Sponsored by: The FreeBSD Foundation MFC after: 1 week --- sys/compat/freebsd32/freebsd32.h | 6 ++++ sys/kern/kern_proc.c | 58 ++++++++++++++++++++++++++++++++ sys/sys/sysctl.h | 1 + sys/sys/user.h | 6 ++++ 4 files changed, 71 insertions(+) diff --git a/sys/compat/freebsd32/freebsd32.h b/sys/compat/freebsd32/freebsd32.h index 8376e956f322..94f886e79d71 100644 --- a/sys/compat/freebsd32/freebsd32.h +++ b/sys/compat/freebsd32/freebsd32.h @@ -362,6 +362,12 @@ struct kinfo_proc32 { int ki_tdflags; }; +struct kinfo_sigtramp32 { + uint32_t ksigtramp_start; + uint32_t ksigtramp_end; + uint32_t ksigtramp_spare[4]; +}; + struct kld32_file_stat_1 { int version; /* set to sizeof(struct kld_file_stat_1) */ char name[MAXPATHLEN]; diff --git a/sys/kern/kern_proc.c b/sys/kern/kern_proc.c index b8195de24d9e..3dc1a584d854 100644 --- a/sys/kern/kern_proc.c +++ b/sys/kern/kern_proc.c @@ -2631,6 +2631,60 @@ sysctl_kern_proc_osrel(SYSCTL_HANDLER_ARGS) return (error); } +static int +sysctl_kern_proc_sigtramp(SYSCTL_HANDLER_ARGS) +{ + int *name = (int *)arg1; + u_int namelen = arg2; + struct proc *p; + struct kinfo_sigtramp kst; + const struct sysentvec *sv; + int error; +#ifdef COMPAT_FREEBSD32 + struct kinfo_sigtramp32 kst32; +#endif + + if (namelen != 1) + return (EINVAL); + + error = pget((pid_t)name[0], PGET_CANDEBUG, &p); + if (error != 0) + return (error); + sv = p->p_sysent; +#ifdef COMPAT_FREEBSD32 + if ((req->flags & SCTL_MASK32) != 0) { + bzero(&kst32, sizeof(kst32)); + if (SV_PROC_FLAG(p, SV_ILP32)) { + if (sv->sv_sigcode_base != 0) { + kst32.ksigtramp_start = sv->sv_sigcode_base; + kst32.ksigtramp_end = sv->sv_sigcode_base + + *sv->sv_szsigcode; + } else { + kst32.ksigtramp_start = sv->sv_psstrings - + *sv->sv_szsigcode; + kst32.ksigtramp_end = sv->sv_psstrings; + } + } + PROC_UNLOCK(p); + error = SYSCTL_OUT(req, &kst32, sizeof(kst32)); + return (error); + } +#endif + bzero(&kst, sizeof(kst)); + if (sv->sv_sigcode_base != 0) { + kst.ksigtramp_start = (char *)sv->sv_sigcode_base; + kst.ksigtramp_end = (char *)sv->sv_sigcode_base + + *sv->sv_szsigcode; + } else { + kst.ksigtramp_start = (char *)sv->sv_psstrings - + *sv->sv_szsigcode; + kst.ksigtramp_end = (char *)sv->sv_psstrings; + } + PROC_UNLOCK(p); + error = SYSCTL_OUT(req, &kst, sizeof(kst)); + 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| @@ -2739,3 +2793,7 @@ static SYSCTL_NODE(_kern_proc, KERN_PROC_UMASK, umask, CTLFLAG_RD | static SYSCTL_NODE(_kern_proc, KERN_PROC_OSREL, osrel, CTLFLAG_RW | CTLFLAG_ANYBODY | CTLFLAG_MPSAFE, sysctl_kern_proc_osrel, "Process binary osreldate"); + +static SYSCTL_NODE(_kern_proc, KERN_PROC_SIGTRAMP, sigtramp, CTLFLAG_RD | + CTLFLAG_MPSAFE, sysctl_kern_proc_sigtramp, + "Process signal trampoline location"); diff --git a/sys/sys/sysctl.h b/sys/sys/sysctl.h index 64292baccc38..8e70a12f1354 100644 --- a/sys/sys/sysctl.h +++ b/sys/sys/sysctl.h @@ -530,6 +530,7 @@ SYSCTL_ALLOWED_TYPES(UINT64, uint64_t *a; unsigned long long *b; ); #define KERN_PROC_PS_STRINGS 38 /* get ps_strings location */ #define KERN_PROC_UMASK 39 /* process umask */ #define KERN_PROC_OSREL 40 /* osreldate for process binary */ +#define KERN_PROC_SIGTRAMP 41 /* signal trampoline location */ /* * KERN_IPC identifiers diff --git a/sys/sys/user.h b/sys/sys/user.h index d2e2b6e71284..e926fe871c95 100644 --- a/sys/sys/user.h +++ b/sys/sys/user.h @@ -498,6 +498,12 @@ struct kinfo_kstack { int _kkst_ispare[16]; /* Space for more stuff. */ }; +struct kinfo_sigtramp { + void *ksigtramp_start; + void *ksigtramp_end; + void *ksigtramp_spare[4]; +}; + #ifdef _KERNEL /* Flags for kern_proc_out function. */ #define KERN_PROC_NOTHREADS 0x1