0

目标:仅当使用 O_RDONLY 标志调用 openat 时才写入 trace_pipe。我已经构建了结构,查看此处包含的格式 /sys/kernel/debug/tracing/events/syscalls/sys_enter_open/format

问题我认为我没有访问 flags 字段,因为看起来第二个 if 语句总是错误的。 问题:我是否正确访问了标志字段?有没有办法打印标志变量内容?

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";
4

1 回答 1

1

所以你提到以下检查总是评估为假:

if (flags == O_RDONLY)

这可能是因为有更多的标志,而不仅仅是通过变量O_RDONLY传递给的标志。从手册页:openat()flagsopenat()

参数标志必须包括以下访问模式之一:O_RDONLY、、O_WRONLYO_RDWR。这些请求分别以只读、只写或读/写方式打开文件。

此外,零个或多个文件创建标志和文件状态标志可以在 flags 中按位' d 。文件创建标志是, , , , , , ,和. 文件状态标志是下面列出的所有剩余标志。这两组标志的区别在于文件创建标志影响打开操作本身的语义,而文件状态标志影响后续I/O操作的语义。可以检索和(在某些情况下)修改文件状态标志;详情见。O_CLOEXECO_CREATO_DIRECTORYO_EXCLO_NOCTTYO_NOFOLLOWO_TMPFILEO_TRUNCfcntl(2)

因此,您可能想要检查它们是否包含标志,而不是检查您flags是否等于,通过像这样对其进行位掩码:O_RDONLY

if (flags & O_RDONLY)

至于打印 的值flags,它可能是可行的(未经测试):

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

        if (flags & O_RDONLY)
                bpf_trace_printk(fmt, sizeof(fmt), flags); 
于 2019-08-30T09:13:07.093 回答