Skip to content

Commit

Permalink
chore(driver): properly only support ia32 for x86_64 architecture.
Browse files Browse the repository at this point in the history
This is that kmod already supported. Start with feature parity then eventually expand to support
compat binaries on all supported architectures.

Signed-off-by: Federico Di Pierro <[email protected]>
  • Loading branch information
FedeDP committed Jul 11, 2023
1 parent 700ef53 commit f4d5c8f
Show file tree
Hide file tree
Showing 4 changed files with 73 additions and 30 deletions.
16 changes: 15 additions & 1 deletion driver/bpf/probe.c
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,16 @@ BPF_PROBE("raw_syscalls/", sys_enter, sys_enter_args)

if (bpf_in_ia32_syscall())
{
#ifdef CONFIG_X86_64
id = convert_ia32_to_64(id);
if (id == 0)
{
return 0;
}
#else
// TODO: unsupported
return 0;
#endif
}

#if defined(CAPTURE_SOCKETCALL) && defined(BPF_SUPPORTS_RAW_TRACEPOINTS)
Expand Down Expand Up @@ -111,9 +118,16 @@ 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(id == 0)
{
return 0;
}
#else
// TODO: unsupported
return 0;
#endif
}

#if defined(CAPTURE_SOCKETCALL) && defined(BPF_SUPPORTS_RAW_TRACEPOINTS)
Expand Down
75 changes: 47 additions & 28 deletions driver/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -2109,6 +2109,25 @@ static inline void g_n_tracepoint_hit_inc(void)
#endif
}

static inline bool kmod_in_ia32_syscall(void)
{
#if defined(CONFIG_X86_64) && defined(CONFIG_IA32_EMULATION)
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 9, 0)
if (in_ia32_syscall())
#else
if (unlikely(task_thread_info(current)->status & TS_COMPAT))
#endif
return true;
#elif defined(CONFIG_ARM64)
if (unlikely(task_thread_info(current)->flags & _TIF_32BIT))
return true;
#elif defined(CONFIG_S390)
if (unlikely(task_thread_info(current)->flags & _TIF_31BIT))
return true;
#endif /* CONFIG_X86_64 */
return false;
}

TRACEPOINT_PROBE(syscall_enter_probe, struct pt_regs *regs, long id)
{
struct event_data_t event_data = {};
Expand All @@ -2129,24 +2148,20 @@ TRACEPOINT_PROBE(syscall_enter_probe, struct pt_regs *regs, long id)
event_data.event_info.syscall_data.id = id;
event_data.compat = false;

if (kmod_in_ia32_syscall())
{
#if defined(CONFIG_X86_64) && defined(CONFIG_IA32_EMULATION)
/*
* If this is a 32bit syscall running on a 64bit kernel (see the CONFIG_IA32_EMULATION
* kernel flag), we convert it to 64bit syscall.
*/
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 9, 0)
if (in_ia32_syscall()) {
#else
if (unlikely(task_thread_info(current)->status & TS_COMPAT)) {
#endif
event_data.compat = true;
event_data.event_info.syscall_data.id = g_ia32_64_map[id];
if (event_data.event_info.syscall_data.id == 0)
if(event_data.event_info.syscall_data.id == 0)
{
return;
return;
}
}
#else
// TODO: unsupported
return;
#endif
}

g_n_tracepoint_hit_inc();

Expand Down Expand Up @@ -2254,26 +2269,30 @@ TRACEPOINT_PROBE(syscall_exit_probe, struct pt_regs *regs, long ret)
event_data.extract_socketcall_params = false;
event_data.compat = false;

if (kmod_in_ia32_syscall())
{
#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
*/
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 9, 0)
if (in_ia32_syscall() && event_data.event_info.syscall_data.id != __NR_execve) {
#else
if (unlikely((task_thread_info(current)->status & TS_COMPAT) && event_data.event_info.syscall_data.id != __NR_execve)) {
#endif
event_data.compat = true;
event_data.event_info.syscall_data.id = g_ia32_64_map[event_data.event_info.syscall_data.id];
if (event_data.event_info.syscall_data.id == 0)
/*
* TODO: is this still needed? 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
*/
if (event_data.event_info.syscall_data.id != __NR_execve)
{
return;
event_data.compat = true;
event_data.event_info.syscall_data.id = g_ia32_64_map[event_data.event_info.syscall_data.id];
if(event_data.event_info.syscall_data.id == 0)
{
return;
}
}
}
#else
// TODO: unsupported
return;
#endif
}

g_n_tracepoint_hit_inc();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,16 @@ int BPF_PROG(sys_enter,

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)
{
return 0;
}
#else
// TODO: unsupported
return 0;
#endif
}

#ifdef CAPTURE_SOCKETCALL
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,16 @@ 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)
if(syscall_id == 0)
{
return 0;
}
#else
// TODO: unsupported
return 0;
#endif
}

#ifdef CAPTURE_SOCKETCALL
Expand Down

0 comments on commit f4d5c8f

Please sign in to comment.