forked from OSchip/llvm-project
[Sanitizers] intercept FreeBSD procctl
Reviewers: vitalybuka, emaster Reviewed-By: viatelybuka Differential Revision: https://reviews.llvm.org/D127069
This commit is contained in:
parent
6eb0f8e285
commit
c06ef17359
|
@ -10349,6 +10349,42 @@ INTERCEPTOR(int, sigaltstack, void *ss, void *oss) {
|
|||
#define INIT_SIGALTSTACK
|
||||
#endif
|
||||
|
||||
#if SANITIZER_INTERCEPT_PROCCTL
|
||||
INTERCEPTOR(int, procctl, int idtype, u64 id, int cmd, uptr data) {
|
||||
void *ctx;
|
||||
COMMON_INTERCEPTOR_ENTER(ctx, procctl, idtype, id, cmd, data);
|
||||
static const int PROC_REAP_ACQUIRE = 2;
|
||||
static const int PROC_REAP_RELEASE = 3;
|
||||
static const int PROC_REAP_STATUS = 4;
|
||||
static const int PROC_REAP_GETPIDS = 5;
|
||||
static const int PROC_REAP_KILL = 6;
|
||||
if (cmd < PROC_REAP_ACQUIRE || cmd > PROC_REAP_KILL) {
|
||||
COMMON_INTERCEPTOR_READ_RANGE(ctx, (void *)data, sizeof(int));
|
||||
} else {
|
||||
// reap_acquire/reap_release bears no arguments.
|
||||
if (cmd > PROC_REAP_RELEASE) {
|
||||
unsigned int reapsz;
|
||||
switch (cmd) {
|
||||
case PROC_REAP_STATUS:
|
||||
reapsz = struct_procctl_reaper_status_sz;
|
||||
break;
|
||||
case PROC_REAP_GETPIDS:
|
||||
reapsz = struct_procctl_reaper_pids_sz;
|
||||
break;
|
||||
case PROC_REAP_KILL:
|
||||
reapsz = struct_procctl_reaper_kill_sz;
|
||||
break;
|
||||
}
|
||||
COMMON_INTERCEPTOR_READ_RANGE(ctx, (void *)data, reapsz);
|
||||
}
|
||||
}
|
||||
return REAL(procctl)(idtype, id, cmd, data);
|
||||
}
|
||||
#define INIT_PROCCTL COMMON_INTERCEPT_FUNCTION(procctl)
|
||||
#else
|
||||
#define INIT_PROCCTL
|
||||
#endif
|
||||
|
||||
#if SANITIZER_INTERCEPT_UNAME
|
||||
INTERCEPTOR(int, uname, struct utsname *utsname) {
|
||||
#if SANITIZER_LINUX
|
||||
|
@ -10708,6 +10744,7 @@ static void InitializeCommonInterceptors() {
|
|||
INIT_QSORT_R;
|
||||
INIT_BSEARCH;
|
||||
INIT_SIGALTSTACK;
|
||||
INIT_PROCCTL
|
||||
INIT_UNAME;
|
||||
INIT___XUNAME;
|
||||
|
||||
|
|
|
@ -901,6 +901,10 @@ bool internal_sigismember(__sanitizer_sigset_t *set, int signum) {
|
|||
return k_set->sig[idx] & ((uptr)1 << bit);
|
||||
}
|
||||
#elif SANITIZER_FREEBSD
|
||||
uptr internal_procctl(int type, int id, int cmd, void *data) {
|
||||
return internal_syscall(SYSCALL(procctl), type, id, cmd, data);
|
||||
}
|
||||
|
||||
void internal_sigdelset(__sanitizer_sigset_t *set, int signum) {
|
||||
sigset_t *rset = reinterpret_cast<sigset_t *>(set);
|
||||
sigdelset(rset, signum);
|
||||
|
@ -2186,7 +2190,8 @@ void CheckASLR() {
|
|||
}
|
||||
#elif SANITIZER_FREEBSD
|
||||
int aslr_status;
|
||||
if (UNLIKELY(procctl(P_PID, 0, PROC_ASLR_STATUS, &aslr_status) == -1)) {
|
||||
int r = internal_procctl(P_PID, 0, PROC_ASLR_STATUS, &aslr_status);
|
||||
if (UNLIKELY(r == -1)) {
|
||||
// We're making things less 'dramatic' here since
|
||||
// the cmd is not necessarily guaranteed to be here
|
||||
// just yet regarding FreeBSD release
|
||||
|
|
|
@ -82,6 +82,7 @@ uptr internal_clone(int (*fn)(void *), void *child_stack, int flags, void *arg,
|
|||
#endif
|
||||
int internal_uname(struct utsname *buf);
|
||||
#elif SANITIZER_FREEBSD
|
||||
uptr internal_procctl(int type, int id, int cmd, void *data);
|
||||
void internal_sigdelset(__sanitizer_sigset_t *set, int signum);
|
||||
#elif SANITIZER_NETBSD
|
||||
void internal_sigdelset(__sanitizer_sigset_t *set, int signum);
|
||||
|
|
|
@ -593,6 +593,7 @@
|
|||
#define SANITIZER_INTERCEPT_UNAME (SI_POSIX && !SI_FREEBSD)
|
||||
#define SANITIZER_INTERCEPT___XUNAME SI_FREEBSD
|
||||
#define SANITIZER_INTERCEPT_FLOPEN SI_FREEBSD
|
||||
#define SANITIZER_INTERCEPT_PROCCTL SI_FREEBSD
|
||||
|
||||
// This macro gives a way for downstream users to override the above
|
||||
// interceptor macros irrespective of the platform they are on. They have
|
||||
|
|
|
@ -205,6 +205,10 @@ unsigned struct_audio_buf_info_sz = sizeof(struct audio_buf_info);
|
|||
unsigned struct_ppp_stats_sz = sizeof(struct ppp_stats);
|
||||
unsigned struct_sioc_sg_req_sz = sizeof(struct sioc_sg_req);
|
||||
unsigned struct_sioc_vif_req_sz = sizeof(struct sioc_vif_req);
|
||||
unsigned struct_procctl_reaper_status_sz = sizeof(struct __sanitizer_procctl_reaper_status);
|
||||
unsigned struct_procctl_reaper_pidinfo_sz = sizeof(struct __sanitizer_procctl_reaper_pidinfo);
|
||||
unsigned struct_procctl_reaper_pids_sz = sizeof(struct __sanitizer_procctl_reaper_pids);
|
||||
unsigned struct_procctl_reaper_kill_sz = sizeof(struct __sanitizer_procctl_reaper_kill);
|
||||
const unsigned long __sanitizer_bufsiz = BUFSIZ;
|
||||
|
||||
const unsigned IOCTL_NOT_PRESENT = 0;
|
||||
|
|
|
@ -424,6 +424,38 @@ struct __sanitizer__ttyent {
|
|||
char *ty_group;
|
||||
};
|
||||
|
||||
// procctl reaper data for PROCCTL_REAPER flags
|
||||
struct __sanitizer_procctl_reaper_status {
|
||||
unsigned int rs_flags;
|
||||
unsigned int rs_children;
|
||||
unsigned int rs_descendants;
|
||||
pid_t rs_reaper;
|
||||
pid_t rs_pid;
|
||||
unsigned int rs_pad0[15];
|
||||
};
|
||||
|
||||
struct __sanitizer_procctl_reaper_pidinfo {
|
||||
pid_t pi_pid;
|
||||
pid_t pi_subtree;
|
||||
unsigned int pi_flags;
|
||||
unsigned int pi_pad0[15];
|
||||
};
|
||||
|
||||
struct __sanitizer_procctl_reaper_pids {
|
||||
unsigned int rp_count;
|
||||
unsigned int rp_pad0[15];
|
||||
struct __sanitize_procctl_reapper_pidinfo *rp_pids;
|
||||
};
|
||||
|
||||
struct __sanitizer_procctl_reaper_kill {
|
||||
int rk_sig;
|
||||
unsigned int rk_flags;
|
||||
pid_t rk_subtree;
|
||||
unsigned int rk_killed;
|
||||
pid_t rk_fpid;
|
||||
unsigned int rk_pad[15];
|
||||
};
|
||||
|
||||
# define IOC_NRBITS 8
|
||||
# define IOC_TYPEBITS 8
|
||||
# if defined(__powerpc__) || defined(__powerpc64__) || defined(__mips__)
|
||||
|
@ -480,6 +512,11 @@ extern unsigned struct_ppp_stats_sz;
|
|||
extern unsigned struct_sioc_sg_req_sz;
|
||||
extern unsigned struct_sioc_vif_req_sz;
|
||||
|
||||
extern unsigned struct_procctl_reaper_status_sz;
|
||||
extern unsigned struct_procctl_reaper_pidinfo_sz;
|
||||
extern unsigned struct_procctl_reaper_pids_sz;
|
||||
extern unsigned struct_procctl_reaper_kill_sz;
|
||||
|
||||
// ioctl request identifiers
|
||||
|
||||
// A special value to mark ioctls that are not present on the target platform,
|
||||
|
|
|
@ -0,0 +1,28 @@
|
|||
// RUN: %clangxx %s -o %t && %run %t %p
|
||||
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/procctl.h>
|
||||
|
||||
int main() {
|
||||
struct procctl_reaper_status status = {0};
|
||||
int res, aslr;
|
||||
res = procctl(P_PID, getpid(), PROC_REAP_STATUS, &status);
|
||||
if (res < 0) {
|
||||
assert(errno == EPERM);
|
||||
return 0;
|
||||
}
|
||||
|
||||
assert(status.rs_flags >= REAPER_STATUS_OWNED);
|
||||
|
||||
res = procctl(P_PID, getpid(), PROC_ASLR_STATUS, &aslr);
|
||||
if (res < 0) {
|
||||
assert(errno == EPERM);
|
||||
return 0;
|
||||
}
|
||||
|
||||
assert(aslr >= PROC_ASLR_FORCE_ENABLE);
|
||||
|
||||
return 0;
|
||||
}
|
Loading…
Reference in New Issue