From 7390661fe7ff3c04ce097259a06bfdd53a554c3f Mon Sep 17 00:00:00 2001 From: Grzegorz Nosek Date: Wed, 26 Jul 2023 15:23:24 +0200 Subject: [PATCH] fix(modern_bpf): fix NULL dereference in signal_deliver filler The `signal_deliver` filler can be called with info=NULL (`SEND_SIG_NOINFO`). Despite all I've been led to believe with eBPF, this does cause an actual NULL dereference in the kernel, promptly killing the machine (as the offending thread dies while holding the spinlock in get_signal). So let's check the pointer before we dereference it. Signed-off-by: Grzegorz Nosek Co-Authored-By: Andrea Terzolo --- .../attached/events/signal_deliver.bpf.c | 63 ++++++++++--------- 1 file changed, 33 insertions(+), 30 deletions(-) diff --git a/driver/modern_bpf/programs/attached/events/signal_deliver.bpf.c b/driver/modern_bpf/programs/attached/events/signal_deliver.bpf.c index 1b7da84dbd..3c28415194 100644 --- a/driver/modern_bpf/programs/attached/events/signal_deliver.bpf.c +++ b/driver/modern_bpf/programs/attached/events/signal_deliver.bpf.c @@ -33,43 +33,46 @@ int BPF_PROG(signal_deliver, /* Try to find the source pid */ pid_t spid = 0; - switch(sig) + if(info != NULL) { - case SIGKILL: - spid = info->_sifields._kill._pid; - break; - - case SIGTERM: - case SIGHUP: - case SIGINT: - case SIGTSTP: - case SIGQUIT: - { - int si_code = info->si_code; - if(si_code == SI_USER || - si_code == SI_QUEUE || - si_code <= 0) + switch(sig) { - /* This is equivalent to `info->si_pid` where - * `si_pid` is a macro `_sifields._kill._pid` - */ + case SIGKILL: spid = info->_sifields._kill._pid; + break; + + case SIGTERM: + case SIGHUP: + case SIGINT: + case SIGTSTP: + case SIGQUIT: + { + int si_code = info->si_code; + if(si_code == SI_USER || + si_code == SI_QUEUE || + si_code <= 0) + { + /* This is equivalent to `info->si_pid` where + * `si_pid` is a macro `_sifields._kill._pid` + */ + spid = info->_sifields._kill._pid; + } + break; } - break; - } - case SIGCHLD: - spid = info->_sifields._sigchld._pid; - break; + case SIGCHLD: + spid = info->_sifields._sigchld._pid; + break; - default: - spid = 0; - break; - } + default: + spid = 0; + break; + } - if(sig >= SIGRTMIN && sig <= SIGRTMAX) - { - spid = info->_sifields._rt._pid; + if(sig >= SIGRTMIN && sig <= SIGRTMAX) + { + spid = info->_sifields._rt._pid; + } } /* Parameter 1: spid (type: PT_PID) */