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

When 32-bit applications run on x86-64 machines, the tracee loses tracking of syscalls like socket and connect. #3676

Closed
lclin56 opened this issue Nov 7, 2023 · 11 comments · Fixed by #3709

Comments

@lclin56
Copy link

lclin56 commented Nov 7, 2023

Description

I hope to trace the syscall calls of a new process within a container. When I tested with this program, I encountered a problem: if the connect connection fails, I won't be able to see the records of calls such as socket and connect printed by tracee-ebpf.

This is the C language code for my test program:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>

int main() {
    int sockfd;
    struct sockaddr_in server_addr;

    sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if (sockfd < 0) {
        perror("Could not create socket");
        return 1;
    }

    memset(&server_addr, 0, sizeof(server_addr));
    server_addr.sin_family = AF_INET;
    server_addr.sin_port = htons(23);
    if (inet_pton(AF_INET, "192.168.56.33", &server_addr.sin_addr) <= 0) {
        perror("Invalid address/ Address not supported");
        close(sockfd);
        return 1;
    }

    if (connect(sockfd, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) {
        perror("Connection Failed");
        close(sockfd);
        return 1;
    }

    printf("Connected to the server successfully.\n");

    // ...

    close(sockfd);

    return 0;
}

This is the command line I use to run tracee:

sudo ./tracee-ebpf -e syscalls --capabilities bypass=true -s container=9cfe36e4c902 -s follow -s pid=new -o out-file:out.log

This is the output of tracee-ebpf:

TIME             CONTAINER_ID  UID    COMM             PID/host        TID/host        RET              EVENT                     ARGS
14:04:40:522894  9cfe36e4c902  0      bash             34     /25221   34     /25221   0                clone                     flags: CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID, stack: 0x0, parent_tid: 0x0, child_tid: 0x7f24b167ea10, tls: 139795571926848
14:04:40:523640  9cfe36e4c902  0      bash             34     /25221   34     /25221   34               getpid                    
14:04:40:523785  9cfe36e4c902  0      bash             34     /25221   34     /25221   0                rt_sigprocmask            how: 2, set: 0x55d322fafb00, oldset: 0x0, sigsetsize: 8
14:04:40:524395  9cfe36e4c902  0      bash             34     /25221   34     /25221   0                rt_sigaction              signum: 20, act: 0x7fff8c868020, oldact: 0x7fff8c8680c0, sigsetsize: 8
14:04:40:524901  9cfe36e4c902  0      bash             34     /25221   34     /25221   0                rt_sigaction              signum: 21, act: 0x7fff8c868020, oldact: 0x7fff8c8680c0, sigsetsize: 8
14:04:40:525025  9cfe36e4c902  0      bash             34     /25221   34     /25221   0                rt_sigaction              signum: 22, act: 0x7fff8c868030, oldact: 0x7fff8c8680d0, sigsetsize: 8
14:04:40:525150  9cfe36e4c902  0      bash             34     /25221   34     /25221   0                setpgid                   pid: 34, pgid: 34
14:04:40:525427  9cfe36e4c902  0      bash             34     /25221   34     /25221   0                rt_sigprocmask            how: 0, set: 0x7fff8c8681b0, oldset: 0x7fff8c868230, sigsetsize: 8
14:04:40:525561  9cfe36e4c902  0      bash             34     /25221   34     /25221   0                ioctl                     fd: 255, request: 21520, arg: 140735551013276
14:04:40:525755  9cfe36e4c902  0      bash             34     /25221   34     /25221   0                rt_sigprocmask            how: 2, set: 0x7fff8c868230, oldset: 0x0, sigsetsize: 8
14:04:40:526407  9cfe36e4c902  0      bash             34     /25221   34     /25221   0                close                     fd: 4
14:04:40:526797  9cfe36e4c902  0      bash             34     /25221   34     /25221   0                read                      fd: 3, buf: 0x7fff8c8682ff, count: 1
14:04:40:526857  9cfe36e4c902  0      bash             34     /25221   34     /25221   0                close                     fd: 3
14:04:40:526920  9cfe36e4c902  0      bash             34     /25221   34     /25221   0                rt_sigaction              signum: 1, act: 0x7fff8c868240, oldact: 0x0, sigsetsize: 8
14:04:40:526989  9cfe36e4c902  0      bash             34     /25221   34     /25221   0                rt_sigaction              signum: 4, act: 0x7fff8c868240, oldact: 0x0, sigsetsize: 8
14:04:40:527040  9cfe36e4c902  0      bash             34     /25221   34     /25221   0                rt_sigaction              signum: 5, act: 0x7fff8c868240, oldact: 0x0, sigsetsize: 8
14:04:40:527090  9cfe36e4c902  0      bash             34     /25221   34     /25221   0                rt_sigaction              signum: 6, act: 0x7fff8c868240, oldact: 0x0, sigsetsize: 8
14:04:40:527140  9cfe36e4c902  0      bash             34     /25221   34     /25221   0                rt_sigaction              signum: 8, act: 0x7fff8c868240, oldact: 0x0, sigsetsize: 8
14:04:40:527191  9cfe36e4c902  0      bash             34     /25221   34     /25221   0                rt_sigaction              signum: 7, act: 0x7fff8c868240, oldact: 0x0, sigsetsize: 8
14:04:40:527310  9cfe36e4c902  0      bash             34     /25221   34     /25221   0                rt_sigaction              signum: 11, act: 0x7fff8c868240, oldact: 0x0, sigsetsize: 8
14:04:40:527361  9cfe36e4c902  0      bash             34     /25221   34     /25221   0                rt_sigaction              signum: 31, act: 0x7fff8c868240, oldact: 0x0, sigsetsize: 8
14:04:40:527412  9cfe36e4c902  0      bash             34     /25221   34     /25221   0                rt_sigaction              signum: 13, act: 0x7fff8c868240, oldact: 0x0, sigsetsize: 8
14:04:40:527484  9cfe36e4c902  0      bash             34     /25221   34     /25221   0                rt_sigaction              signum: 14, act: 0x7fff8c868240, oldact: 0x0, sigsetsize: 8
14:04:40:527535  9cfe36e4c902  0      bash             34     /25221   34     /25221   0                rt_sigaction              signum: 24, act: 0x7fff8c868240, oldact: 0x0, sigsetsize: 8
14:04:40:527645  9cfe36e4c902  0      bash             34     /25221   34     /25221   0                rt_sigaction              signum: 25, act: 0x7fff8c868240, oldact: 0x0, sigsetsize: 8
14:04:40:527696  9cfe36e4c902  0      bash             34     /25221   34     /25221   0                rt_sigaction              signum: 26, act: 0x7fff8c868240, oldact: 0x0, sigsetsize: 8
14:04:40:527805  9cfe36e4c902  0      bash             34     /25221   34     /25221   0                rt_sigaction              signum: 10, act: 0x7fff8c868240, oldact: 0x0, sigsetsize: 8
14:04:40:527915  9cfe36e4c902  0      bash             34     /25221   34     /25221   0                rt_sigaction              signum: 12, act: 0x7fff8c868240, oldact: 0x0, sigsetsize: 8
14:04:40:527974  9cfe36e4c902  0      bash             34     /25221   34     /25221   0                rt_sigaction              signum: 2, act: 0x7fff8c868140, oldact: 0x7fff8c8681e0, sigsetsize: 8
14:04:40:528088  9cfe36e4c902  0      bash             34     /25221   34     /25221   0                rt_sigaction              signum: 3, act: 0x7fff8c868140, oldact: 0x7fff8c8681e0, sigsetsize: 8
14:04:40:528148  9cfe36e4c902  0      bash             34     /25221   34     /25221   0                rt_sigaction              signum: 15, act: 0x7fff8c868140, oldact: 0x7fff8c8681e0, sigsetsize: 8
14:04:40:528199  9cfe36e4c902  0      bash             34     /25221   34     /25221   0                rt_sigaction              signum: 17, act: 0x7fff8c868140, oldact: 0x7fff8c8681e0, sigsetsize: 8
14:04:40:528280  9cfe36e4c902  0      bash             34     /25221   34     /25221   0                execve                    pathname: ./test_connect, argv: [./test_connect], envp: <nil>
14:04:40:528700  9cfe36e4c902  0      test_connect     34     /25221   34     /25221   1473548288       brk                       addr: 0x0
14:04:40:529046  9cfe36e4c902  0      test_connect     34     /25221   34     /25221   -2               access                    pathname: /etc/ld.so.nohwcap, mode: 
14:04:40:529210  9cfe36e4c902  0      test_connect     34     /25221   34     /25221   0                access                    pathname: /etc/ld.so.preload, mode: R_OK
14:04:40:529269  9cfe36e4c902  0      test_connect     34     /25221   34     /25221   3                openat                    dirfd: -100, pathname: /etc/ld.so.preload, flags: O_RDONLY|O_CLOEXEC, mode: 0
14:04:40:529350  9cfe36e4c902  0      test_connect     34     /25221   34     /25221   0                close                     fd: 3
14:04:40:529466  9cfe36e4c902  0      test_connect     34     /25221   34     /25221   3                openat                    dirfd: -100, pathname: /etc/ld.so.cache, flags: O_RDONLY|O_CLOEXEC, mode: 0
14:04:40:529534  9cfe36e4c902  0      test_connect     34     /25221   34     /25221   0                close                     fd: 3
14:04:40:529590  9cfe36e4c902  0      test_connect     34     /25221   34     /25221   -2               access                    pathname: /etc/ld.so.nohwcap, mode: 
14:04:40:529705  9cfe36e4c902  0      test_connect     34     /25221   34     /25221   3                openat                    dirfd: -100, pathname: /lib/i386-linux-gnu/libc.so.6, flags: O_RDONLY|O_CLOEXEC, mode: 0
14:04:40:530237  9cfe36e4c902  0      test_connect     34     /25221   34     /25221   512              read                      fd: 3, buf: 0xffad5cd0, count: 512
14:04:40:530321  9cfe36e4c902  0      test_connect     34     /25221   34     /25221   0                mprotect                  addr: 0xf7efe000, len: 4096, prot: PROT_NONE
14:04:40:530398  9cfe36e4c902  0      test_connect     34     /25221   34     /25221   0                close                     fd: 3
14:04:40:530498  9cfe36e4c902  0      test_connect     34     /25221   34     /25221   0                set_thread_area           u_info: 0xffad60e0
14:04:40:530889  9cfe36e4c902  0      test_connect     34     /25221   34     /25221   0                mprotect                  addr: 0xf7eff000, len: 8192, prot: PROT_READ
14:04:40:530975  9cfe36e4c902  0      test_connect     34     /25221   34     /25221   0                mprotect                  addr: 0x56635000, len: 4096, prot: PROT_READ
14:04:40:531034  9cfe36e4c902  0      test_connect     34     /25221   34     /25221   0                mprotect                  addr: 0xf7f38000, len: 4096, prot: PROT_READ
14:04:40:531091  9cfe36e4c902  0      test_connect     34     /25221   34     /25221   0                munmap                    addr: 0xf7f05000, length: 22207
14:04:43:548918  9cfe36e4c902  0      test_connect     34     /25221   34     /25221   4                dup                       oldfd: 2
14:04:43:549079  9cfe36e4c902  0      test_connect     34     /25221   34     /25221   1473548288       brk                       addr: 0x0
14:04:43:549162  9cfe36e4c902  0      test_connect     34     /25221   34     /25221   1473683456       brk                       addr: 0x57d6a000
14:04:43:549225  9cfe36e4c902  0      test_connect     34     /25221   34     /25221   1473687552       brk                       addr: 0x57d6b000
14:04:43:549412  9cfe36e4c902  0      test_connect     34     /25221   34     /25221   40               write                     fd: 4, buf: 0x57d492c0, count: 40
14:04:43:549581  9cfe36e4c902  0      test_connect     34     /25221   34     /25221   0                close                     fd: 4
14:04:43:549665  9cfe36e4c902  0      test_connect     34     /25221   34     /25221   1473683456       brk                       addr: 0x57d6a000
14:04:43:549749  9cfe36e4c902  0      test_connect     34     /25221   34     /25221   0                close                     fd: 3
14:04:43:549920  9cfe36e4c902  0      test_connect     34     /25221   34     /25221   0                exit_group                status: 1
End of events stream
Stats: {EventCount:{value:59} EventsFiltered:{value:0} NetCapCount:{value:0} BPFLogsCount:{value:0} ErrorCount:{value:0} LostEvCount:{value:0} LostWrCount:{value:0} LostNtCapCount:{value:0} LostBPFLogsCount:{value:0}}

Output of tracee version:

Tracee version: "v0.18.0-rc-38-g52b27bbc7"

Output of uname -a:

Linux yxu 5.4.0-152-generic #169~18.04.1-Ubuntu SMP Wed Jun 7 22:22:24 UTC 2023 x86_64 x86_64 x86_64 GNU/Linux

Additional details

I expect to see the "socket" call that creates the socketfd and the "connect" call that establishes the connection in the output of tracee-ebpf, even if the connect fails. However, it seems that the records of these two calls are not visible in the output.

@rafaeldtinoco rafaeldtinoco self-assigned this Nov 7, 2023
@rafaeldtinoco rafaeldtinoco added this to the v0.20.0 milestone Nov 7, 2023
@geyslan
Copy link
Member

geyslan commented Nov 7, 2023

@lclin56, I've only tested on the host so far, but I noticed that the connect call wasn't being detected because it wasn't finished (wrong address without timeout) - you can press ctrl+c in your test and see the connect event being printed by tracee. (I've used -s comm=conntest to filter only the scope of the PoC).

sudo ./dist/tracee-ebpf -s comm=conntest -e socket,connect --capabilities bypass=true

TIME             UID    COMM             PID     TID     RET              EVENT                     ARGS
09:20:34:365833  1000   conntest         31310   31310   3                socket                    domain: AF_INET, type: SOCK_STREAM, protocol: 0
09:20:34:365877  1000   conntest         31310   31310   -512             connect                   sockfd: 3, addr: map[sa_family:AF_INET sin_addr:8.8.8.8 sin_port:23], addrlen: 16

So I changed your PoC to reflect that. Please do more tests using it and let us know the results.

int main() {
    int sockfd;
    struct sockaddr_in server_addr;
    struct timeval timeout;

    sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if (sockfd < 0) {
        perror("Could not create socket");
        return 1;
    }

    memset(&server_addr, 0, sizeof(server_addr));
    server_addr.sin_family = AF_INET;
    server_addr.sin_port = htons(23);
    if (inet_pton(AF_INET, "0.0.0.0", &server_addr.sin_addr) <= 0) {
        perror("Invalid address/ Address not supported");
        close(sockfd);
        return 1;
    }

    // Set timeout
    timeout.tv_sec = 3;   // 3 seconds
    timeout.tv_usec = 0;  // 0 microseconds
    if (setsockopt(sockfd, SOL_SOCKET, SO_SNDTIMEO, (const char*)&timeout, sizeof timeout) < 0) {
        perror("setsockopt failed");
        close(sockfd);
        return 1;
    }

    printf("About to call connect()...\n");

    if (connect(sockfd, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) {
        perror("Connection Failed");
        close(sockfd);
        return 1;
    }

    printf("Connected to the server successfully.\n");

    // ...

    close(sockfd);

    return 0;
}

@lclin56
Copy link
Author

lclin56 commented Nov 8, 2023

I'm sorry, I missed an important detail. The compilation command I used for the PoC is
gcc -m32 conntest.c -o conntest
I compiled your modified PoC code with this command, but I didn't see any "socket" and "connect" calls in the tracee-ebpf output. What I can confirm is that when I traced the program with systemtap, I did see "socket" and "connect" calls.
Here is the command line to run tracee-ebpf:
sudo ./tracee-ebpf -s comm=conntest -e syscalls --capabilities bypass=true
This is the output of tracee-ebpf:

09:47:08:883697  1001   conntest         11546   11546   1466892288       brk                       addr: 0x0
09:47:08:884558  1001   conntest         11546   11546   -2               access                    pathname: /etc/ld.so.nohwcap, mode: 
09:47:08:884935  1001   conntest         11546   11546   0                access                    pathname: /etc/ld.so.preload, mode: R_OK
09:47:08:885229  1001   conntest         11546   11546   3                openat                    dirfd: -100, pathname: /etc/ld.so.preload, flags: O_RDONLY|O_CLOEXEC, mode: 0
09:47:08:885567  1001   conntest         11546   11546   0                close                     fd: 3
09:47:08:885867  1001   conntest         11546   11546   3                openat                    dirfd: -100, pathname: /etc/ld.so.cache, flags: O_RDONLY|O_CLOEXEC, mode: 0
09:47:08:886295  1001   conntest         11546   11546   0                close                     fd: 3
09:47:08:886665  1001   conntest         11546   11546   -2               access                    pathname: /etc/ld.so.nohwcap, mode: 
09:47:08:886828  1001   conntest         11546   11546   3                openat                    dirfd: -100, pathname: /lib32/libc.so.6, flags: O_RDONLY|O_CLOEXEC, mode: 0
09:47:08:887055  1001   conntest         11546   11546   512              read                      fd: 3, buf: 0xffcfe9a0, count: 512
09:47:08:887257  1001   conntest         11546   11546   0                mprotect                  addr: 0xf7f3e000, len: 4096, prot: PROT_NONE
09:47:08:887422  1001   conntest         11546   11546   0                close                     fd: 3
09:47:08:887642  1001   conntest         11546   11546   0                set_thread_area           u_info: 0xffcfedb0
09:47:08:887866  1001   conntest         11546   11546   0                mprotect                  addr: 0xf7f3f000, len: 8192, prot: PROT_READ
09:47:08:888218  1001   conntest         11546   11546   0                mprotect                  addr: 0x56639000, len: 4096, prot: PROT_READ
09:47:08:888499  1001   conntest         11546   11546   0                mprotect                  addr: 0xf7f88000, len: 4096, prot: PROT_READ
09:47:08:888793  1001   conntest         11546   11546   0                munmap                    addr: 0xf7f45000, length: 88200
09:47:08:889525  1001   conntest         11546   11546   1466892288       brk                       addr: 0x0
09:47:08:889815  1001   conntest         11546   11546   1467027456       brk                       addr: 0x57711000
09:47:08:890078  1001   conntest         11546   11546   1467031552       brk                       addr: 0x57712000
09:47:08:890362  1001   conntest         11546   11546   27               write                     fd: 1, buf: 0x576f0160, count: 27
09:47:08:890928  1001   conntest         11546   11546   4                dup                       oldfd: 2
09:47:08:891234  1001   conntest         11546   11546   38               write                     fd: 4, buf: 0x576f06d0, count: 38
09:47:08:891544  1001   conntest         11546   11546   0                close                     fd: 4
09:47:08:891821  1001   conntest         11546   11546   1467027456       brk                       addr: 0x57711000
09:47:08:892077  1001   conntest         11546   11546   0                close                     fd: 3
09:47:08:892378  1001   conntest         11546   11546   0                exit_group                status: 1

Based on the current results, it seems that there might be some issues with tracee when tracing 32-bit programs running on an x86-64 machine.

@lclin56 lclin56 changed the title When establishing a connection fails, the trace to the connect call is lost. When 32-bit applications run on x86-64 machines, the tracee loses tracking of syscalls like socket and connect. Nov 9, 2023
@geyslan

This comment was marked as outdated.

@geyslan

This comment was marked as off-topic.

@rafaeldtinoco
Copy link
Contributor

Ok, I would start with:

sudo perf ftrace --graph-opts depth=10 -- ./yourcode

and pick the execution path from both, the env where it worked and where it did not. Check if there are any changes in execution path.

Then I would place a printk in the hooks for the event before any other logic and check if the hook is even being executed.

Finally, it could be that the 32bit syscall emulation doesn't include the security_socket event, but the regular syscall execution path does (at least in the older kernels). If newer kernels have those, you are able to track the change and discover why it works in newer ones.

@geyslan
Copy link
Member

geyslan commented Nov 21, 2023

Not working environment 5.15.0-86-generic (socket)

__ia32_compat_sys_socketcall() {
 2)               |    __check_object_size() {
 2)               |      __check_object_size.part.0() {
 2)   0.197 us    |        check_stack_object();
 2)   0.502 us    |      }
 2)   0.793 us    |    }
 2)               |    __sys_socket() {
 2)               |      __sock_create() {
 2)               |        security_socket_create() {
 2)               |          apparmor_socket_create() {
 2)               |            __cond_resched() {
 2)   0.151 us    |              rcu_all_qs();
 2)   0.441 us    |            }
 2)   0.783 us    |          }
 2)   1.278 us    |        }
 2)               |        sock_alloc() {
 2)               |          new_inode_pseudo() {
 2)               |            alloc_inode() {
 2)               |              sock_alloc_inode() {
 2)               |                kmem_cache_alloc() {
 2)               |                  __cond_resched() {
 2)   0.151 us    |                    rcu_all_qs();
 2)   0.439 us    |                  }
 2)   0.151 us    |                  should_failslab();
 2)   0.155 us    |                  rcu_read_unlock_strict();
 2)   0.156 us    |                  rcu_read_unlock_strict();
 2)   0.153 us    |                  obj_cgroup_charge();
 2)   0.157 us    |                  rcu_read_unlock_strict();
 2)   0.177 us    |                  mod_objcg_state();
 2)   0.153 us    |                  rcu_read_unlock_strict();
 2)   3.759 us    |                }
 2)   0.153 us    |                __init_waitqueue_head();
 2)   4.408 us    |              }
 2)               |              inode_init_always() {
 2)               |                make_kuid() {
 2)   0.156 us    |                  map_id_range_down();
 2)   0.444 us    |                }
 2)               |                make_kgid() {
 2)   0.160 us    |                  map_id_range_down();
 2)   0.448 us    |                }
 2)   0.154 us    |                __init_rwsem();
 2)   0.161 us    |                __init_rwsem();
 2)               |                security_inode_alloc() {
 2)               |                  kmem_cache_alloc() {
 2)   0.333 us    |                    __cond_resched();
 2)   0.153 us    |                    should_failslab();
 2)   1.117 us    |                  }
 2)   1.408 us    |                }
 2)   3.703 us    |              }
 2)   9.210 us    |            }
 2)   0.157 us    |            _raw_spin_lock();
 2)   9.819 us    |          }
 2)   0.153 us    |          get_next_ino();
 2) + 10.524 us   |        }
 2)   0.151 us    |        try_module_get();
 2)   0.152 us    |        rcu_read_unlock_strict();
 2)               |        inet_create() {
 2)               |          inet_create.part.0.constprop.0() {
 2)   0.154 us    |            rcu_read_unlock_strict();
 2)               |            sk_alloc() {
 2)               |              sk_prot_alloc() {
 2)               |                kmem_cache_alloc() {
 2)               |                  __cond_resched() {
 2)   0.151 us    |                    rcu_all_qs();
 2)   0.444 us    |                  }
 2)   0.157 us    |                  should_failslab();
 2)   0.153 us    |                  rcu_read_unlock_strict();
 2)   0.154 us    |                  rcu_read_unlock_strict();
 2)   0.155 us    |                  obj_cgroup_charge();
 2)   0.153 us    |                  rcu_read_unlock_strict();
 2)   0.155 us    |                  mod_objcg_state();
 2)   0.153 us    |                  rcu_read_unlock_strict();
 2)   3.418 us    |                }
 2)               |                security_sk_alloc() {
 2)               |                  __kmalloc() {
 2)   0.167 us    |                    kmalloc_slab();
 2)   0.237 us    |                    __cond_resched();
 2)   0.155 us    |                    should_failslab();
 2)   1.261 us    |                  }
 2)   1.567 us    |                }
 2)   0.152 us    |                try_module_get();
 2)   5.996 us    |              }
 2)   0.155 us    |              __init_waitqueue_head();
 2)               |              mem_cgroup_sk_alloc() {
 2)   0.151 us    |                rcu_read_unlock_strict();
 2)   0.151 us    |                rcu_read_unlock_strict();
 2)   0.731 us    |              }
 2)               |              cgroup_sk_alloc() {
 2)   0.152 us    |                rcu_read_unlock_strict();
 2)   0.152 us    |                rcu_read_unlock_strict();
 2)   0.157 us    |                rcu_read_unlock_strict();
 2)   1.134 us    |              }
 2)   0.151 us    |              rcu_read_unlock_strict();
 2)   0.150 us    |              rcu_read_unlock_strict();
 2)   9.826 us    |            }
 2)               |            sock_init_data() {
 2)               |              sock_init_data_uid() {
 2)   0.153 us    |                init_timer_key();
 2)   0.484 us    |              }
 2)   0.770 us    |            }
 2)               |            tcp_v4_init_sock() {
 2)               |              tcp_init_sock() {
 2)               |                tcp_init_xmit_timers() {
 2)               |                  inet_csk_init_xmit_timers() {
 2)   0.154 us    |                    init_timer_key();
 2)   0.152 us    |                    init_timer_key();
 2)   0.153 us    |                    init_timer_key();
 2)   1.022 us    |                  }
 2)               |                  hrtimer_init() {
 2)   0.196 us    |                    __hrtimer_init();
 2)   0.494 us    |                  }
 2)               |                  hrtimer_init() {
 2)   0.174 us    |                    __hrtimer_init();
 2)   0.463 us    |                  }
 2)   2.907 us    |                }
 2)   0.151 us    |                jiffies_to_usecs();
 2)               |                tcp_assign_congestion_control() {
 2)   0.151 us    |                  try_module_get();
 2)   0.152 us    |                  rcu_read_unlock_strict();
 2)   0.952 us    |                }
 2)   4.863 us    |              }
 2)   5.408 us    |            }
 2) + 17.488 us   |          }
 2) + 17.898 us   |        }
 2)   0.151 us    |        try_module_get();
 2)   0.151 us    |        module_put();
 2)               |        security_socket_post_create() {
 2)   0.207 us    |          apparmor_socket_post_create();
 2)   0.529 us    |        }
 2) + 32.513 us   |      }
 2)               |      get_unused_fd_flags() {
 2)               |        alloc_fd() {
 2)   0.198 us    |          _raw_spin_lock();
 2)   0.157 us    |          expand_files();
 2)   0.845 us    |        }
 2)   1.148 us    |      }
 2)               |      sock_alloc_file() {
 2)               |        alloc_file_pseudo() {
 2)               |          d_alloc_pseudo() {
 2)               |            __d_alloc() {
 2)               |              kmem_cache_alloc() {
 2)               |                __cond_resched() {
 2)   0.155 us    |                  rcu_all_qs();
 2)   0.443 us    |                }
 2)   0.150 us    |                should_failslab();
 2)   0.155 us    |                rcu_read_unlock_strict();
 2)   0.156 us    |                rcu_read_unlock_strict();
 2)   0.153 us    |                obj_cgroup_charge();
 2)   0.151 us    |                rcu_read_unlock_strict();
 2)   0.174 us    |                mod_objcg_state();
 2)   0.151 us    |                rcu_read_unlock_strict();
 2)   3.195 us    |              }
 2)   0.257 us    |              d_set_d_op();
 2)   4.104 us    |            }
 2)   4.395 us    |          }
 2)   0.157 us    |          mntget();
 2)               |          d_instantiate() {
 2)   0.273 us    |            security_d_instantiate();
 2)   0.156 us    |            _raw_spin_lock();
 2)               |            __d_instantiate() {
 2)   0.233 us    |              d_flags_for_inode();
 2)   0.159 us    |              _raw_spin_lock();
 2)   0.852 us    |            }
 2)   1.852 us    |          }
 2)               |          alloc_file() {
 2)               |            alloc_empty_file() {
 2)               |              __alloc_file() {
 2)               |                kmem_cache_alloc() {
 2)               |                  __cond_resched() {
 2)   0.151 us    |                    rcu_all_qs();
 2)   0.439 us    |                  }
 2)   0.155 us    |                  should_failslab();
 2)   0.151 us    |                  rcu_read_unlock_strict();
 2)   0.151 us    |                  rcu_read_unlock_strict();
 2)   0.154 us    |                  obj_cgroup_charge();
 2)   0.489 us    |                  ___slab_alloc();
 2)   0.158 us    |                  rcu_read_unlock_strict();
 2)   0.162 us    |                  mod_objcg_state();
 2)   0.158 us    |                  rcu_read_unlock_strict();
 2)   3.518 us    |                }
 2)               |                security_file_alloc() {
 2)               |                  kmem_cache_alloc() {
 2)   0.229 us    |                    __cond_resched();
 2)   0.152 us    |                    should_failslab();
 2)   0.867 us    |                  }
 2)               |                  apparmor_file_alloc_security() {
 2)   0.227 us    |                    __cond_resched();
 2)   0.522 us    |                  }
 2)   1.848 us    |                }
 2)   0.154 us    |                __mutex_init();
 2)   6.087 us    |              }
 2)   6.388 us    |            }
 2)   6.795 us    |          }
 2) + 14.365 us   |        }
 2)   0.158 us    |        stream_open();
 2) + 14.948 us   |      }
 2)   0.154 us    |      fd_install();
 2) + 49.642 us   |    }
 2) + 51.433 us   |  }

Working environment 6.5.11-1-MANJARO (socket)

__ia32_sys_socket() {
  9)               |    __sys_socket() {
  9)               |      __sock_create() {
  9)               |        security_socket_create() {
  9)   0.076 us    |          bpf_lsm_socket_create();
  9)   0.116 us    |          apparmor_socket_create();
  9)   0.851 us    |        }
  9)               |        sock_alloc() {
  9)               |          new_inode_pseudo() {
  9)               |            alloc_inode() {
  9)               |              sock_alloc_inode() {
  9)               |                kmem_cache_alloc_lru() {
  9)   0.123 us    |                  should_failslab();
  9)   0.099 us    |                  __rcu_read_lock();
  9)               |                  __get_obj_cgroup_from_memcg() {
  9)   0.071 us    |                    __rcu_read_lock();
  9)   0.078 us    |                    __rcu_read_unlock();
  9)   0.351 us    |                  }
  9)   0.103 us    |                  __rcu_read_unlock();
  9)   0.108 us    |                  __rcu_read_lock();
  9)   0.076 us    |                  __rcu_read_lock();
  9)   0.078 us    |                  __rcu_read_unlock();
  9)   0.082 us    |                  __rcu_read_unlock();
  9)               |                  memcg_list_lru_alloc() {
  9)   0.253 us    |                    __rcu_read_lock();
  9)   0.173 us    |                    __rcu_read_unlock();
  9)   0.839 us    |                  }
  9)   0.076 us    |                  __rcu_read_lock();
  9)   0.076 us    |                  __rcu_read_unlock();
  9)   0.097 us    |                  obj_cgroup_charge();
  9)   0.116 us    |                  __rcu_read_lock();
  9)   0.213 us    |                  __rcu_read_unlock();
  9)   0.122 us    |                  mod_objcg_state();
  9)   0.075 us    |                  __rcu_read_lock();
  9)   0.075 us    |                  __rcu_read_unlock();
  9)   4.630 us    |                }
  9)   0.076 us    |                __init_waitqueue_head();
  9)   4.927 us    |              }
  9)               |              inode_init_always() {
  9)               |                make_kuid() {
  9)   0.092 us    |                  map_id_range_down();
  9)   0.240 us    |                }
  9)               |                make_kgid() {
  9)   0.076 us    |                  map_id_range_down();
  9)   0.215 us    |                }
  9)   0.075 us    |                __init_rwsem();
  9)   0.075 us    |                __init_rwsem();
  9)               |                security_inode_alloc() {
  9)               |                  kmem_cache_alloc() {
  9)   0.072 us    |                    should_failslab();
  9)   0.238 us    |                  }
  9)   0.123 us    |                  bpf_lsm_inode_alloc_security();
  9)   0.983 us    |                }
  9)   2.346 us    |              }
  9)   7.995 us    |            }
  9)   0.077 us    |            _raw_spin_lock();
  9)   0.074 us    |            _raw_spin_unlock();
  9)   8.516 us    |          }
  9)   0.074 us    |          get_next_ino();
  9)   8.936 us    |        }
  9)   0.302 us    |        __rcu_read_lock();
  9)   0.079 us    |        try_module_get();
  9)   0.075 us    |        __rcu_read_unlock();
  9)               |        inet_create() {
  9)   0.077 us    |          __rcu_read_lock();
  9)   0.102 us    |          __rcu_read_unlock();
  9)               |          sk_alloc() {
  9)               |            sk_prot_alloc() {
  9)               |              kmem_cache_alloc() {
  9)   0.171 us    |                should_failslab();
  9)   0.373 us    |                __rcu_read_lock();
  9)               |                __get_obj_cgroup_from_memcg() {
  9)   0.075 us    |                  __rcu_read_lock();
  9)   0.074 us    |                  __rcu_read_unlock();
  9)   0.350 us    |                }
  9)   0.075 us    |                __rcu_read_unlock();
  9)   0.082 us    |                obj_cgroup_charge();
  9)   0.090 us    |                __rcu_read_lock();
  9)   0.074 us    |                __rcu_read_unlock();
  9)   0.302 us    |                mod_objcg_state();
  9)   0.076 us    |                __rcu_read_lock();
  9)   0.074 us    |                __rcu_read_unlock();
  9)   2.798 us    |              }
  9)               |              security_sk_alloc() {
  9)   0.206 us    |                bpf_lsm_sk_alloc_security();
  9)               |                apparmor_sk_alloc_security() {
  9)               |                  kmalloc_trace() {
  9)   0.425 us    |                    __kmem_cache_alloc_node();
  9)   0.571 us    |                  }
  9)   0.724 us    |                }
  9)   1.891 us    |              }
  9)   0.078 us    |              try_module_get();
  9)   5.064 us    |            }
  9)   0.079 us    |            __init_waitqueue_head();
  9)               |            mem_cgroup_sk_alloc() {
  9)   0.210 us    |              __rcu_read_lock();
  9)   0.076 us    |              __rcu_read_lock();
  9)   0.080 us    |              __rcu_read_unlock();
  9)   0.076 us    |              __rcu_read_unlock();
  9)   0.805 us    |            }
  9)               |            cgroup_sk_alloc() {
  9)   0.077 us    |              __rcu_read_lock();
  9)   0.299 us    |              __rcu_read_lock();
  9)   0.199 us    |              __rcu_read_unlock();
  9)   0.075 us    |              __rcu_read_lock();
  9)   0.079 us    |              __rcu_read_unlock();
  9)   0.283 us    |              __rcu_read_unlock();
  9)   1.602 us    |            }
  9)   0.076 us    |            __rcu_read_lock();
  9)   0.146 us    |            __rcu_read_unlock();
  9)   0.075 us    |            __rcu_read_lock();
  9)   0.274 us    |            __rcu_read_unlock();
  9)   9.057 us    |          }
  9)               |          sock_init_data() {
  9)               |            sock_init_data_uid() {
  9)   0.077 us    |              init_timer_key();
  9)   0.240 us    |            }
  9)   0.471 us    |          } /* sock_init_data */
  9)               |          tcp_v4_init_sock() {
  9)               |            tcp_init_sock() {
  9)               |              tcp_init_xmit_timers() {
  9)               |                inet_csk_init_xmit_timers() {
  9)   0.201 us    |                  init_timer_key();
  9)   0.076 us    |                  init_timer_key();
  9)   0.088 us    |                  init_timer_key();
  9)   0.688 us    |                }
  9)               |                hrtimer_init() {
  9)   0.099 us    |                  __hrtimer_init();
  9)   0.389 us    |                }
  9)               |                hrtimer_init() {
  9)   0.088 us    |                  __hrtimer_init();
  9)   0.346 us    |                }
  9)   1.860 us    |              }
  9)   0.076 us    |              jiffies_to_usecs();
  9)               |              tcp_assign_congestion_control() {
  9)   0.073 us    |                __rcu_read_lock();
  9)   0.148 us    |                try_module_get();
  9)   0.075 us    |                __rcu_read_unlock();
  9)   0.593 us    |              }
  9)   0.083 us    |              _raw_spin_lock();
  9)   0.076 us    |              _raw_spin_unlock();
  9)   3.417 us    |            }
  9)   3.659 us    |          }
  9) + 14.221 us   |        }
  9)   0.077 us    |        try_module_get();
  9)   0.073 us    |        module_put();
  9)               |        security_socket_post_create() {
  9)   0.078 us    |          bpf_lsm_socket_post_create();
  9)   0.112 us    |          apparmor_socket_post_create();
  9)   0.457 us    |        }
  9) + 26.082 us   |      }
  9)               |      get_unused_fd_flags() {
  9)               |        alloc_fd() {
  9)   0.078 us    |          _raw_spin_lock();
  9)   0.081 us    |          expand_files();
  9)   0.077 us    |          _raw_spin_unlock();
  9)   0.549 us    |        }
  9)   0.687 us    |      }
  9)               |      sock_alloc_file() {
  9)               |        alloc_file_pseudo() {
  9)               |          d_alloc_pseudo() {
  9)               |            __d_alloc() {
  9)               |              kmem_cache_alloc_lru() {
  9)   0.074 us    |                should_failslab();
  9)   0.075 us    |                __rcu_read_lock();
  9)               |                __get_obj_cgroup_from_memcg() {
  9)   0.076 us    |                  __rcu_read_lock();
  9)   0.075 us    |                  __rcu_read_unlock();
  9)   0.351 us    |                }
  9)   0.075 us    |                __rcu_read_unlock();
  9)   0.076 us    |                __rcu_read_lock();
  9)   0.072 us    |                __rcu_read_lock();
  9)   0.078 us    |                __rcu_read_unlock();
  9)   0.075 us    |                __rcu_read_unlock();
  9)               |                memcg_list_lru_alloc() {
  9)   0.076 us    |                  __rcu_read_lock();
  9)   0.247 us    |                  __rcu_read_unlock();
  9)   0.642 us    |                }
  9)   0.075 us    |                __rcu_read_lock();
  9)   0.075 us    |                __rcu_read_unlock();
  9)               |                obj_cgroup_charge() {
  9)   0.075 us    |                  __rcu_read_lock();
  9)   0.075 us    |                  __rcu_read_lock();
  9)   0.078 us    |                  __rcu_read_unlock();
  9)   0.075 us    |                  __rcu_read_unlock();
  9)   0.082 us    |                  try_charge_memcg();
  9)               |                  memcg_account_kmem() {
  9)   0.135 us    |                    __mod_memcg_state();
  9)   0.279 us    |                  }
  9)   0.080 us    |                  __rcu_read_lock();
  9)   0.073 us    |                  __rcu_read_unlock();
  9)   0.083 us    |                  refill_obj_stock();
  9)   1.641 us    |                }
  9)   0.075 us    |                __rcu_read_lock();
  9)   0.074 us    |                __rcu_read_unlock();
  9)   0.200 us    |                mod_objcg_state();
  9)   0.076 us    |                __rcu_read_lock();
  9)   0.075 us    |                __rcu_read_unlock();
  9)   5.148 us    |              }
  9)   0.199 us    |              d_set_d_op();
  9)   5.590 us    |            }
  9)   5.744 us    |          }
  9)   0.082 us    |          mntget();
  9)               |          d_instantiate() {
  9)               |            security_d_instantiate() {
  9)   0.074 us    |              bpf_lsm_d_instantiate();
  9)   0.422 us    |            }
  9)   0.082 us    |            _raw_spin_lock();
  9)               |            __d_instantiate() {
  9)   0.163 us    |              d_flags_for_inode();
  9)   0.081 us    |              _raw_spin_lock();
  9)   0.074 us    |              _raw_spin_unlock();
  9)   0.613 us    |            }
  9)   0.074 us    |            _raw_spin_unlock();
  9)   1.539 us    |          }
  9)               |          alloc_file() {
  9)               |            alloc_empty_file() {
  9)               |              kmem_cache_alloc() {
  9)   0.072 us    |                should_failslab();
  9)   0.077 us    |                __rcu_read_lock();
  9)               |                __get_obj_cgroup_from_memcg() {
  9)               |                  __rcu_read_lock() {
  9)   0.126 us    |                    irq_enter_rcu();
  9)   0.582 us    |                    __sysvec_irq_work();
  9)   0.177 us    |                    irq_exit_rcu();
  9)   0.073 us    |                    raw_irqentry_exit_cond_resched();
  9)   1.661 us    |                  }
  9)   0.079 us    |                  __rcu_read_unlock();
  9)   1.933 us    |                }
  9)   0.077 us    |                __rcu_read_unlock();
  9)   0.086 us    |                obj_cgroup_charge();
  9)   0.096 us    |                __rcu_read_lock();
  9)   0.073 us    |                __rcu_read_unlock();
  9)   0.091 us    |                mod_objcg_state();
  9)   0.075 us    |                __rcu_read_lock();
  9)   0.099 us    |                __rcu_read_unlock();
  9)   3.492 us    |              }
  9)               |              init_file() {
  9)               |                security_file_alloc() {
  9)               |                  kmem_cache_alloc() {
  9)   0.075 us    |                    should_failslab();
  9)   0.239 us    |                  }
  9)   0.098 us    |                  hook_file_alloc_security();
  9)   0.073 us    |                  bpf_lsm_file_alloc_security();
  9)   0.084 us    |                  apparmor_file_alloc_security();
  9)   0.890 us    |                }
  9)   0.077 us    |                __mutex_init();
  9)   1.175 us    |              }
  9)   4.921 us    |            }
  9)   5.254 us    |          }
  9) + 13.044 us   |        }
  9)   0.075 us    |        stream_open();
  9) + 13.501 us   |      }
  9)   0.081 us    |      fd_install();
  9) + 40.793 us   |    }
  9) + 41.015 us   |  }

I haven't detected evident differences:

❯ grep 'security_' working_socket.perf 
  9)               |        security_socket_create() {
  9)               |                security_inode_alloc() {
  9)               |              security_sk_alloc() {
  9)               |        security_socket_post_create() {
  9)               |            security_d_instantiate() {
  9)               |                security_file_alloc() {

❯ grep 'security_' not_working_socket.perf 
  2)               |        security_socket_create() {
  2)               |                security_inode_alloc() {
  2)               |                security_sk_alloc() {
  2)               |        security_socket_post_create() {
  2)   0.273 us    |            security_d_instantiate();
  2)               |                security_file_alloc() {

@rafaeldtinoco
Copy link
Contributor

rafaeldtinoco commented Nov 21, 2023

Well, __ia32_compat_sys_socketcall and __ia32_sys_socket is what you are probably looking for then (I was =D).

One is the old syscall entry (multiplexed), used in 32-bit environments, and the other is the new syscall handler (one handler per functionality: socket, bind, connect, listen, accept, ...).

This explains why the cmdline:

sudo ./tracee-ebpf -s comm=conntest -e syscalls --capabilities bypass=true

does not give you a "socket" event. Because that event not exist, instead the socketcall event should appear. (1) We should check if we're able to trace socketcall() events when running binaries in compatibility mode.

image

Also, In the eBPF code we have:

image

SO we could be returning there. (2) needs to check if security_socket_create event is generated when socketcall(SYS_SOCKET) is called.

@rafaeldtinoco
Copy link
Contributor

rafaeldtinoco commented Nov 21, 2023

Okay so with:

sudo ./dist/tracee --install-path /tmp/tracee --cache cache-type=mem --cache mem-cache-size=512 --output option:sort-events --output json --output option:parse-arguments --events security_socket_create

Im able to pick the the security_socket_connect event A SINGLE TIME:

image

when originated by a "socketcall" entry and it was likely a bug in the logic (as you can see there is no socket fd, no sockaddr values, within the event).

All other times I was not able to generate a security_socket_event when executing the example code. Very likely because of the logic that checks if the syscall that is generating the security event was "connect" (and in our case it is not). There is also the fact that we have to check, if socketcall(CONNECT) is the entry point to the kernel, we have to pick in security_socket_create hook in a different way (and then generate the event with the correct arguments).

Because of (likely) some race condition, the event worked when it should have not.


My proposal to you @geyslan:

(1)

You have to check the "current syscall id" inside security_socket_connect(). Then, if its connect the current logic is correct. If the entry syscall was socketcall, you will have to extract the arguments for the event from different places:

int connect(int socket, const struct sockaddr *address, socklen_t address_len);
int syscall(SYS_socketcall, int call, unsigned long *args);

I believe the initial 2 args should be skipped, sockfd would come from the 3rd argument, etc. Then you have to emit security_socket_event if the entry point was socketcall as well (not only connect). But only if the 2nd argument was SYS_CONNECT.

(2)

Unfortunately thats not all. We have now to do the same thing for all "network security events". All the possible socketcall() commands should now deal with the fact that the entry point can be socketcall(COMMAND). Then the same logic inside their eBPF Programs should apply (extract the security network event arguments from the 3rd argument and on).

Ping me if you have any doubt. Cheers!

@geyslan
Copy link
Member

geyslan commented Nov 22, 2023

I've been checking this a bit more today by running tracee like:

sudo ./dist/tracee-ebpf -s comm=conntest64,conntest32 -e socket,socketcall,unlink --capabilities bypass=true

And by having conntest64 and conntest32 emitting only those three events to facilitate the debugging process (unlink in both 32 and 64-bit, socket in 64-bit and socketcall in 32-bit).

With that I was expecting to catch the socketcall event on the old kernel but it also didn't happen. So I gone up to sys_enter hook for checking the event ID translation where I detected that some events are getting wrong 32-bit ids:

      conntest32-368511  [000] d.... 13564.227211: bpf_trace_printk: sys_enter: is_compat
      conntest32-368511  [000] d.... 13564.227211: bpf_trace_printk: sys_enter: id before 102 (socketcall)
      conntest32-368511  [000] d.... 13564.227212: bpf_trace_printk: sys_enter: id after  384

sudo bpftool map dump name sys_32_to_64_ma | less

...
        "key": 102,
        "value": 384
...

id after (value) should be 473:

image

So, this 0dbc8e4 enables getting socketcall:

TIME             UID    COMM             PID     TID     RET              EVENT                     ARGS
17:46:01:681627  1000   conntest32       467146  467146  3                socketcall                call: 1, args: 0xffce1ee0
17:46:01:681689  1000   conntest32       467146  467146  -2               unlink                    pathname: /tmp/whatever
17:46:01:683082  1000   conntest32       467146  467146  0                socketcall                call: 14, args: 0xffce1eb8
17:46:01:683628  1000   conntest32       467146  467146  -111             socketcall                call: 3, args: 0xffce1ee0

@rafaeldtinoco what you proposed will be tackled next. 👍🏼

@rafaeldtinoco
Copy link
Contributor

id after (value) should be 473:

I had always a constant thinking that the id32s could be broken (no specific testing, etc). Nice catch.

geyslan added a commit to geyslan/tracee that referenced this issue Nov 23, 2023
Depending on the kernel version, 32-bit binaries use either the
socketcall syscall as a entry point for socket syscalls functions, or
the individual syscalls (socket, bind, connect, etc).

Context: aquasecurity#3676
geyslan added a commit to geyslan/tracee that referenced this issue Nov 23, 2023
Depending on the kernel version, 32-bit binaries use either the
socketcall syscall as a entry point for socket syscalls functions, or
the individual syscalls (socket, bind, connect, etc).

Context: aquasecurity#3676
geyslan added a commit to geyslan/tracee that referenced this issue Nov 23, 2023
The Linux kernel version determines x86 32-bit compatibility: older
versions use 'socketcall' syscall for socket functions (like socket,
bind, connect), while newer versions use individual syscalls directly.

Context: aquasecurity#3676
geyslan added a commit to geyslan/tracee that referenced this issue Nov 23, 2023
The Linux kernel version determines x86 32-bit compatibility: older
versions use 'socketcall' syscall for socket functions (like socket,
bind, connect), while newer versions use individual syscalls directly.

Context: aquasecurity#3676
geyslan added a commit to geyslan/tracee that referenced this issue Nov 23, 2023
The Linux kernel version determines x86 32-bit compatibility: older
versions use 'socketcall' syscall for socket functions (like socket,
bind, connect), while newer versions use individual syscalls directly.

These changes were also tested on an arm64 running an armhf binary.

Context: aquasecurity#3676
rafaeldtinoco pushed a commit that referenced this issue Nov 24, 2023
The Linux kernel version determines x86 32-bit compatibility: older
versions use 'socketcall' syscall for socket functions (like socket,
bind, connect), while newer versions use individual syscalls directly.

These changes were also tested on an arm64 running an armhf binary.

Context: #3676
@rafaeldtinoco
Copy link
Contributor

Fixed by #3709 (same as #3707)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
3 participants