Skip to content

Commit

Permalink
fix(driver): implemented execve and execveat logic to bpf and modern …
Browse files Browse the repository at this point in the history
…bpf too.

A 64bit process that execve's to a 32bit one (eg: a bash shell that executes a 32bit executable),
will receive the execve exit event as 64bit event, even if the compat flag is already set
on the task.

Signed-off-by: Federico Di Pierro <[email protected]>
  • Loading branch information
FedeDP committed Jul 12, 2023
1 parent c9deef4 commit 79990c2
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 8 deletions.
21 changes: 17 additions & 4 deletions driver/bpf/probe.c
Original file line number Diff line number Diff line change
Expand Up @@ -118,11 +118,24 @@ BPF_PROBE("raw_syscalls/", sys_exit, sys_exit_args)

if (bpf_in_ia32_syscall())
{
#ifdef CONFIG_X86_64
id = convert_ia32_to_64(id);
if(id == 0)
#if defined(CONFIG_X86_64) && defined(CONFIG_IA32_EMULATION)
/*
* When a process does execve from 64bit to 32bit, TS_COMPAT is marked true
* but the id of the syscall is __NR_execve, so to correctly parse it we need to
* use 64bit syscall table. On 32bit __NR_execve is equal to __NR_ia32_oldolduname
* which is a very old syscall, not used anymore by most applications
*/
#ifdef __NR_execveat
if (id != __NR_execve && id != __NR_execveat)
#else
if (id != __NR_execve)
#endif
{
return 0;
id = convert_ia32_to_64(id);
if(id == 0)
{
return 0;
}
}
#else
// TODO: unsupported
Expand Down
5 changes: 4 additions & 1 deletion driver/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -2319,13 +2319,16 @@ TRACEPOINT_PROBE(syscall_exit_probe, struct pt_regs *regs, long ret)
{
#if defined(CONFIG_X86_64) && defined(CONFIG_IA32_EMULATION)
/*
* TODO: do we need to add execveat too?
* When a process does execve from 64bit to 32bit, TS_COMPAT is marked true
* but the id of the syscall is __NR_execve, so to correctly parse it we need to
* use 64bit syscall table. On 32bit __NR_execve is equal to __NR_ia32_oldolduname
* which is a very old syscall, not used anymore by most applications
*/
#ifdef __NR_execveat
if (event_data.event_info.syscall_data.id != __NR_execve && event_data.event_info.syscall_data.id != __NR_execveat)
#else
if (event_data.event_info.syscall_data.id != __NR_execve)
#endif
{
event_data.event_info.syscall_data.id =
g_ia32_64_map[event_data.event_info.syscall_data.id];
Expand Down
18 changes: 15 additions & 3 deletions driver/modern_bpf/programs/attached/dispatchers/syscall_exit.bpf.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@
#include <helpers/interfaces/attached_programs.h>
#include <bpf/bpf_helpers.h>

#define X86_64_NR_EXECVE 59
#define X86_64_NR_EXECVEAT 322

/* From linux tree: /include/trace/events/syscall.h
* TP_PROTO(struct pt_regs *regs, long ret),
*/
Expand All @@ -22,10 +25,19 @@ int BPF_PROG(sys_exit,
if(syscalls_dispatcher__check_32bit_syscalls())
{
#if defined(__TARGET_ARCH_x86)
syscall_id = syscalls_dispatcher__convert_ia32_to_64(syscall_id);
if(syscall_id == 0)
/*
* When a process does execve from 64bit to 32bit, TS_COMPAT is marked true
* but the id of the syscall is __NR_execve, so to correctly parse it we need to
* use 64bit syscall table. On 32bit __NR_execve is equal to __NR_ia32_oldolduname
* which is a very old syscall, not used anymore by most applications
*/
if (syscall_id != X86_64_NR_EXECVE && syscall_id != X86_64_NR_EXECVEAT)
{
return 0;
syscall_id = syscalls_dispatcher__convert_ia32_to_64(syscall_id);
if(syscall_id == 0)
{
return 0;
}
}
#else
// TODO: unsupported
Expand Down

0 comments on commit 79990c2

Please sign in to comment.