Skip to content

Commit

Permalink
fix: better timespec support for ia32
Browse files Browse the repository at this point in the history
Signed-off-by: Roberto Scolaro <[email protected]>
  • Loading branch information
therealbobo committed Apr 29, 2024
1 parent 739d3b9 commit 7c60d90
Show file tree
Hide file tree
Showing 6 changed files with 59 additions and 16 deletions.
2 changes: 1 addition & 1 deletion driver/SCHEMA_VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
2.19.6
2.19.7
27 changes: 20 additions & 7 deletions driver/bpf/fillers.h
Original file line number Diff line number Diff line change
Expand Up @@ -809,13 +809,26 @@ FILLER(sys_writev_pwritev_x, true)
static __always_inline int timespec_parse(struct filler_data *data,
unsigned long val)
{
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 18, 0)
struct __kernel_timespec ts = {};
#else
struct timespec ts = {};
#endif
bpf_probe_read_user(&ts, sizeof(ts), (void *)val);
return bpf_push_u64_to_ring(data, ((uint64_t)ts.tv_sec) * 1000000000 + ts.tv_nsec);
#if defined(CONFIG_X86_64) && defined(CONFIG_IA32_EMULATION)
if (!bpf_in_ia32_syscall())
#endif
{
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 18, 0)
struct __kernel_timespec ts = {};
#else
struct timespec ts = {};
#endif
bpf_probe_read_user(&ts, sizeof(ts), (void *)val);
return bpf_push_u64_to_ring(data, ((uint64_t)ts.tv_sec) * 1000000000 + ts.tv_nsec);
}
#if defined(CONFIG_X86_64) && defined(CONFIG_IA32_EMULATION)
else
{
struct timespec ts = {};
bpf_probe_read_user(&ts, sizeof(ts), (void *)val);
return bpf_push_u64_to_ring(data, ((uint32_t)ts.tv_sec) * 1000000000 + ts.tv_nsec);
}
#endif
}

FILLER(sys_nanosleep_e, true)
Expand Down
6 changes: 6 additions & 0 deletions driver/modern_bpf/definitions/struct_flavors.h
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,12 @@ struct modern_bpf__kernel_timespec
long int tv_nsec;
};

struct modern_bpf__kernel_timespec_ia32
{
int tv_sec;
int tv_nsec;
};

/* We use this as a fallback for kernels where `struct __kernel_timex_timeval` is not defined. */
struct modern_bpf__kernel_timex_timeval
{
Expand Down
18 changes: 16 additions & 2 deletions driver/modern_bpf/helpers/store/auxmap_store_params.h
Original file line number Diff line number Diff line change
Expand Up @@ -800,8 +800,7 @@ static __always_inline void auxmap__store_socktuple_param(struct auxiliary_map *
}

unsigned long start_reading_point;
char first_path_byte = *(char *)path;
if(first_path_byte == '\0')
if(path[0] == '\0' && path[1] != '\0')
{
/* Please note exceptions in the `sun_path`:
* Taken from: https://man7.org/linux/man-pages/man7/unix.7.html
Expand All @@ -814,6 +813,21 @@ static __always_inline void auxmap__store_socktuple_param(struct auxiliary_map *
*/
start_reading_point = (unsigned long)path + 1;
}
else if(path[0] == '\0' && path[1] == '\0')
{
// If no path is retrived from kernel, try to read from userspace.
if(direction == OUTBOUND)
{
bpf_probe_read_user_str(path, UNIX_PATH_MAX,
((struct sockaddr_un *)usrsockaddr)->sun_path);
}
else
{
bpf_probe_read_user(path, UNIX_PATH_MAX,
((struct sockaddr_un *)usrsockaddr)->sun_path);
}

}
else
{
start_reading_point = (unsigned long)path;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,17 +38,26 @@ int BPF_PROG(ppoll_e,
/* Parameter 2: timeout (type: PT_RELTIME) */
uint64_t nanosec = 0;
unsigned long ts_pointer = extract__syscall_argument(regs, 2);
if(bpf_core_type_exists(struct __kernel_timespec))
if(!bpf_in_ia32_syscall())
{
struct __kernel_timespec ts = {0};
bpf_probe_read_user(&ts, bpf_core_type_size(struct __kernel_timespec), (void *)ts_pointer);
nanosec = ((uint64_t)ts.tv_sec) * SECOND_TO_NS + ts.tv_nsec;
if(bpf_core_type_exists(struct __kernel_timespec))
{
struct __kernel_timespec ts = {0};
bpf_probe_read_user(&ts, bpf_core_type_size(struct __kernel_timespec), (void *)ts_pointer);
nanosec = ((uint64_t)ts.tv_sec) * SECOND_TO_NS + ts.tv_nsec;
}
else
{
struct modern_bpf__kernel_timespec ts = {0};
bpf_probe_read_user(&ts, sizeof(ts), (void *)ts_pointer);
nanosec = ((uint64_t)ts.tv_sec) * SECOND_TO_NS + ts.tv_nsec;
}
}
else
{
struct modern_bpf__kernel_timespec ts = {0};
struct modern_bpf__kernel_timespec_ia32 ts = {0};
bpf_probe_read_user(&ts, sizeof(ts), (void *)ts_pointer);
nanosec = ((uint64_t)ts.tv_sec) * SECOND_TO_NS + ts.tv_nsec;
nanosec = ((uint32_t)ts.tv_sec) * SECOND_TO_NS + ts.tv_nsec;
}
auxmap__store_u64_param(auxmap, nanosec);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ int BPF_PROG(recvfrom_x,
/* Parameter 3: tuple (type: PT_SOCKTUPLE) */
uint32_t socket_fd = (uint32_t)args[0];
struct sockaddr *usrsockaddr = (struct sockaddr *)args[4];
bpf_printk("recvfrom");
auxmap__store_socktuple_param(auxmap, socket_fd, INBOUND, usrsockaddr);
}
else
Expand Down

0 comments on commit 7c60d90

Please sign in to comment.