Maicake
Maicake

Reputation: 1126

Can't access correctly to tracepoint context struct fields

GOAL: write in the trace_pipe only if openat is called with O_RDONLY flag. I've build the struct looking the format contained here /sys/kernel/debug/tracing/events/syscalls/sys_enter_open/format

PROBLEM I think I'm not accessing to the flags field because it looks like that the second if statement is always false. QUESTION: am I correctly accessing to the flags fields? Is there a way to print flags variable content?

struct syscalls_enter_openat_args {
    __u64 pad;
    int __syscall_nr;
    const char * filename;
    int flags;
    unsigned short modep;
};
SEC("tracepoint/syscalls/sys_enter_openat")
int bpf_sys(struct syscalls_enter_openat_args *ctx)
{
    char fmt[] = "llo\n";
    int flags = ctx->flags;

    if (flags){
        if (flags == O_RDONLY)
            bpf_trace_printk(fmt, sizeof(fmt)); 
    }
    return 0;
}
char _license[] SEC("license") = "GPL";

Upvotes: 0

Views: 371

Answers (1)

Qeole
Qeole

Reputation: 9114

So you mention that the following check always evaluates to false:

if (flags == O_RDONLY)

This may be because there are more flags than just O_RDONLY that are passed to openat() through the variable flags. From the openat() manual page:

The argument flags must include one of the following access modes: O_RDONLY, O_WRONLY, or O_RDWR. These request opening the file read-only, write-only, or read/write, respectively.

In addition, zero or more file creation flags and file status flags can be bitwise-or'd in flags. The file creation flags are O_CLOEXEC, O_CREAT, O_DIRECTORY, O_EXCL, O_NOCTTY, O_NOFOLLOW, O_TMPFILE, and O_TRUNC. The file status flags are all of the remaining flags listed below. The distinction between these two groups of flags is that the file creation flags affect the semantics of the open operation itself, while the file status flags affect the semantics of subsequent I/O operations. The file status flags can be retrieved and (in some cases) modified; see fcntl(2) for details.

So instead of checking if your flags are equal to O_RDONLY, you might want to check if they include the flag, by bit-masking it like this:

if (flags & O_RDONLY)

As for printing the value of flags, it is probably doable with something like this (not tested):

        char fmt[] = "flags: %x\n";
        int flags = ctx->flags;

        if (flags & O_RDONLY)
                bpf_trace_printk(fmt, sizeof(fmt), flags); 

Upvotes: 1

Related Questions