Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: sync release branch 0.11.x #1125

Merged
merged 11 commits into from
May 29, 2023
Merged
2 changes: 1 addition & 1 deletion driver/API_VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
4.0.0
4.0.1
2 changes: 2 additions & 0 deletions driver/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,8 @@ set(DRIVER_SOURCES
ppm_tp.c
ppm_consumer.h
capture_macro.h
socketcall_to_syscall.h
socketcall_to_syscall.c
)

foreach(FILENAME IN LISTS DRIVER_SOURCES)
Expand Down
2 changes: 1 addition & 1 deletion driver/Makefile.in
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
# MIT.txt or GPL.txt for full copies of the license.
#

@DRIVER_NAME@-y += main.o dynamic_params_table.o fillers_table.o flags_table.o ppm_events.o ppm_fillers.o event_table.o syscall_table32.o syscall_table64.o ppm_cputime.o ppm_tp.o
@DRIVER_NAME@-y += main.o dynamic_params_table.o fillers_table.o flags_table.o ppm_events.o ppm_fillers.o event_table.o syscall_table32.o syscall_table64.o ppm_cputime.o ppm_tp.o socketcall_to_syscall.o
obj-m += @[email protected]
ccflags-y := @KBUILD_FLAGS@

Expand Down
2 changes: 1 addition & 1 deletion driver/SCHEMA_VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
2.4.0
2.4.1
40 changes: 31 additions & 9 deletions driver/bpf/filler_helpers.h
Original file line number Diff line number Diff line change
Expand Up @@ -660,14 +660,26 @@ static __always_inline long bpf_fd_to_socktuple(struct filler_data *data,
struct sockaddr_in *usrsockaddr_in = (struct sockaddr_in *)usrsockaddr;

if (is_inbound) {
/* To take inbound info we cannot use the `src_addr` obtained from the syscall
* it could be empty!
* From kernel 3.13 we can take both ipv4 and ipv6 info from here
* https://elixir.bootlin.com/linux/v3.13/source/include/net/sock.h#L164
/* To take peer address info we try to use the kernel where possible.
* TCP allows us to obtain the right information, while the kernel doesn't fill
* `sk->__sk_common.skc_daddr` for UDP connection.
* Instead of having a custom logic for each protocol we try to read from
* kernel structs and if we don't find valid data we fallback to userspace
* structs.
*/
bpf_probe_read_kernel(&sip, sizeof(sip), &sk->__sk_common.skc_daddr);
bpf_probe_read_kernel(&sport, sizeof(sport), &sk->__sk_common.skc_dport);
sport = ntohs(sport);
if(sport != 0)
{
/* We can read from the kernel */
bpf_probe_read_kernel(&sip, sizeof(sip), &sk->__sk_common.skc_daddr);
sport = ntohs(sport);
}
else
{
/* Fallback to userspace struct */
sip = usrsockaddr_in->sin_addr.s_addr;
sport = ntohs(usrsockaddr_in->sin_port);
}
dip = ((struct sockaddr_in *)sock_address)->sin_addr.s_addr;
dport = ntohs(((struct sockaddr_in *)sock_address)->sin_port);
} else {
Expand Down Expand Up @@ -722,10 +734,20 @@ static __always_inline long bpf_fd_to_socktuple(struct filler_data *data,
struct sockaddr_in6 *usrsockaddr_in6 = (struct sockaddr_in6 *)usrsockaddr;

if (is_inbound) {
bpf_probe_read_kernel(&in6, sizeof(in6), &sk->__sk_common.skc_v6_daddr);
sip6 = in6.in6_u.u6_addr8;
bpf_probe_read_kernel(&sport, sizeof(sport), &sk->__sk_common.skc_dport);
sport = ntohs(sport);
if(sport != 0)
{
/* We can read from the kernel */
bpf_probe_read_kernel(&in6, sizeof(in6), &sk->__sk_common.skc_v6_daddr);
sip6 = in6.in6_u.u6_addr8;
sport = ntohs(sport);
}
else
{
/* Fallback to userspace struct */
sip6 = usrsockaddr_in6->sin6_addr.s6_addr;
sport = ntohs(usrsockaddr_in6->sin6_port);
}
dip6 = ((struct sockaddr_in6 *)sock_address)->sin6_addr.s6_addr;
dport = ntohs(((struct sockaddr_in6 *)sock_address)->sin6_port);
} else {
Expand Down
126 changes: 18 additions & 108 deletions driver/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,10 @@ or GPL2.txt for full copies of the license.
#include "ppm.h"
#include "ppm_tp.h"

#ifdef _HAS_SOCKETCALL
#include "socketcall_to_syscall.h"
#endif

#define __NR_ia32_socketcall 102

MODULE_LICENSE("GPL");
Expand Down Expand Up @@ -1361,119 +1365,21 @@ static const unsigned char compat_nas[21] = {
static long convert_network_syscalls(struct pt_regs *regs, long socketcall_syscall)
{
unsigned long __user args[6] = {};
int new_syscall_id = 0;
ppm_syscall_get_arguments(current, regs, args);

/* args[0] is the specific syscall code */
switch(args[0])
{
#ifdef __NR_socket
case SYS_SOCKET:
return __NR_socket;
#endif

#ifdef __NR_socketpair
case SYS_SOCKETPAIR:
return __NR_socketpair;
#endif

case SYS_ACCEPT:
#if defined(CONFIG_S390) && defined(__NR_accept4)
return __NR_accept4;
#elif defined(__NR_accept)
return __NR_accept;
#endif
break;

#ifdef __NR_accept4
case SYS_ACCEPT4:
return __NR_accept4;
#endif

#ifdef __NR_bind
case SYS_BIND:
return __NR_bind;
#endif

#ifdef __NR_listen
case SYS_LISTEN:
return __NR_listen;
#endif

#ifdef __NR_connect
case SYS_CONNECT:
return __NR_connect;
#endif

#ifdef __NR_getsockname
case SYS_GETSOCKNAME:
return __NR_getsockname;
#endif

#ifdef __NR_getpeername
case SYS_GETPEERNAME:
return __NR_getpeername;
#endif

#ifdef __NR_getsockopt
case SYS_GETSOCKOPT:
return __NR_getsockopt;
#endif

#ifdef __NR_setsockopt
case SYS_SETSOCKOPT:
return __NR_setsockopt;
#endif

#ifdef __NR_recv
case SYS_RECV:
return __NR_recv;
#endif

#ifdef __NR_recvfrom
case SYS_RECVFROM:
return __NR_recvfrom;
#endif

#ifdef __NR_recvmsg
case SYS_RECVMSG:
return __NR_recvmsg;
#endif

#ifdef __NR_recvmmsg
case SYS_RECVMMSG:
return __NR_recvmmsg;
#endif

#ifdef __NR_send
case SYS_SEND:
return __NR_send;
#endif

#ifdef __NR_sendto
case SYS_SENDTO:
return __NR_sendto;
#endif
new_syscall_id = socketcall_code_to_syscall_code(args[0]);

#ifdef __NR_sendmsg
case SYS_SENDMSG:
return __NR_sendmsg;
#endif

#ifdef __NR_sendmmsg
case SYS_SENDMMSG:
return __NR_sendmmsg;
#endif

#ifdef __NR_shutdown
case SYS_SHUTDOWN:
return __NR_shutdown;
#endif
default:
break;
/* If we are not able to convert the socketcall code to
* a valid syscall code we return the original socketcall id
* and we send a generic event
*/
if(new_syscall_id == -1)
{
new_syscall_id = socketcall_syscall;
}

// reset NR_socketcall and send a generic event
return socketcall_syscall;
return new_syscall_id;
}

static int load_socketcall_params(struct event_filler_arguments *filler_args)
Expand Down Expand Up @@ -2912,7 +2818,11 @@ int scap_init(void)
goto init_module_err;
}

#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 4, 0)
g_ppm_class = class_create(THIS_MODULE, DRIVER_DEVICE_NAME);
#else
g_ppm_class = class_create(DRIVER_DEVICE_NAME);
#endif
if (IS_ERR(g_ppm_class)) {
pr_err("can't allocate device class\n");
ret = -EFAULT;
Expand Down
49 changes: 32 additions & 17 deletions driver/ppm_events.c
Original file line number Diff line number Diff line change
Expand Up @@ -1258,20 +1258,28 @@ u16 fd_to_socktuple(int fd,
*/
usrsockaddr_in = (struct sockaddr_in *)usrsockaddr;

if (is_inbound) {
/* To take inbound info we cannot use the `src_addr` obtained from the syscall
* it could be empty!
* From kernel 3.13 we can take both ipv4 and ipv6 info from here
* https://elixir.bootlin.com/linux/v3.13/source/include/net/sock.h#L164
if (is_inbound)
{
/* To take peer address info we try to use the kernel where possible.
* TCP allows us to obtain the right information, while the kernel doesn't fill
* `sk->__sk_common.skc_daddr` for UDP connection.
* Instead of having a custom logic for each protocol we try to read from
* kernel structs and if we don't find valid data we fallback to userspace
* structs.
*/
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 13, 0)
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 13, 0)
sport = ntohs(sock->sk->__sk_common.skc_dport);
if(sport != 0)
{
/* We can read from the kernel */
sip = sock->sk->__sk_common.skc_daddr;
sport = ntohs(sock->sk->__sk_common.skc_dport);
#else
/* this is probably wrong, we need to find an alternative in old kernels */
sip = ((struct sockaddr_in *) &sock_address)->sin_addr.s_addr;
}
else
#endif
{
sip = usrsockaddr_in->sin_addr.s_addr;
sport = ntohs(usrsockaddr_in->sin_port);
#endif
}
dip = ((struct sockaddr_in *) &sock_address)->sin_addr.s_addr;
dport = ntohs(((struct sockaddr_in *) &sock_address)->sin_port);
} else {
Expand Down Expand Up @@ -1321,15 +1329,22 @@ u16 fd_to_socktuple(int fd,
*/
usrsockaddr_in6 = (struct sockaddr_in6 *)usrsockaddr;

if (is_inbound) {
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 13, 0)
if (is_inbound)
{
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 13, 0)
sport = ntohs(sock->sk->__sk_common.skc_dport);
if(sport != 0)
{
/* We can read from the kernel */
sip6 = sock->sk->__sk_common.skc_v6_daddr.in6_u.u6_addr8;
sport = ntohs(sock->sk->__sk_common.skc_dport);
#else
/* this is probably wrong, we need to find an alternative in old kernels */
}
else
#endif
{
/* Fallback to userspace struct */
sip6 = usrsockaddr_in6->sin6_addr.s6_addr;
sport = ntohs(usrsockaddr_in6->sin6_port);
#endif
}
dip6 = ((struct sockaddr_in6 *) &sock_address)->sin6_addr.s6_addr;
dport = ntohs(((struct sockaddr_in6 *) &sock_address)->sin6_port);
} else {
Expand Down
5 changes: 5 additions & 0 deletions driver/ppm_version.h
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
#ifndef PPM_VERSION_H_
#define PPM_VERSION_H_

#ifndef UDIG
#include <linux/version.h>
#endif
Expand All @@ -18,3 +21,5 @@
#define PPM_RHEL_RELEASE_CODE 0
#define PPM_RHEL_RELEASE_VERSION(x,y) 0
#endif

#endif /* PPM_VERSION_H_ */
Loading