Skip to content

Commit

Permalink
tools/opensnoop: Display mode for -e, --extended_fields
Browse files Browse the repository at this point in the history
When a program creates a file with mode=0000, it cannot even access the file
itself. It would be helpful if we could track the mode value. so we can know
who did it.

Example:

    open("a.txt", O_WRONLY | O_EXCL | O_CREAT, 0000);

Then:

    $ ls -l a.txt
    ----------. 1 rongtao rongtao 0 Jan 24 09:07 a.txt
    $ cat a.txt
    cat: a.txt: Permission denied

    $ sudo ./opensnoop.py -e
    PID    COMM               FD ERR FLAGS    MODE PATH
    673067 open                3   0 00000301 0000 a.txt
                                              ^^^^

Signed-off-by: Rong Tao <[email protected]>
  • Loading branch information
Rtoax committed Jan 24, 2025
1 parent c8515f7 commit 761d813
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 26 deletions.
28 changes: 22 additions & 6 deletions tools/opensnoop.py
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@
char comm[TASK_COMM_LEN];
const char *fname;
int flags; // EXTENDED_STRUCT_MEMBER
unsigned short mode; // EXTENDED_STRUCT_MEMBER
};
struct data_t {
Expand All @@ -130,6 +131,7 @@
#endif
char name[NAME_MAX];
int flags; // EXTENDED_STRUCT_MEMBER
unsigned short mode; // EXTENDED_STRUCT_MEMBER
};
BPF_PERF_OUTPUT(events);
Expand Down Expand Up @@ -158,6 +160,7 @@
data.ts = tsp / 1000;
data.uid = bpf_get_current_uid_gid();
data.flags = valp->flags; // EXTENDED_STRUCT_MEMBER
data.mode = valp->mode; // EXTENDED_STRUCT_MEMBER
data.ret = PT_REGS_RC(ctx);
SUBMIT_DATA
Expand All @@ -169,12 +172,15 @@
"""

bpf_text_kprobe_header_open = """
int syscall__trace_entry_open(struct pt_regs *ctx, const char __user *filename, int flags)
int syscall__trace_entry_open(struct pt_regs *ctx, const char __user *filename,
int flags, unsigned short mode)
{
"""

bpf_text_kprobe_header_openat = """
int syscall__trace_entry_openat(struct pt_regs *ctx, int dfd, const char __user *filename, int flags)
int syscall__trace_entry_openat(struct pt_regs *ctx, int dfd,
const char __user *filename, int flags,
unsigned short mode)
{
"""

Expand All @@ -183,6 +189,7 @@
int syscall__trace_entry_openat2(struct pt_regs *ctx, int dfd, const char __user *filename, struct open_how *how)
{
int flags = how->flags;
unsigned short mode = how->mode;
"""

bpf_text_kprobe_body = """
Expand All @@ -204,6 +211,7 @@
val.id = id;
val.fname = filename;
val.flags = flags; // EXTENDED_STRUCT_MEMBER
val.mode = mode; // EXTENDED_STRUCT_MEMBER
infotmp.update(&id, &val);
}
Expand All @@ -217,8 +225,10 @@
{
const char __user *filename = (char *)PT_REGS_PARM1(regs);
int flags = PT_REGS_PARM2(regs);
unsigned short mode = PT_REGS_PARM3(regs);
#else
KRETFUNC_PROBE(FNNAME, const char __user *filename, int flags, int ret)
KRETFUNC_PROBE(FNNAME, const char __user *filename, int flags,
unsigned short mode, int ret)
{
#endif
"""
Expand All @@ -230,8 +240,10 @@
int dfd = PT_REGS_PARM1(regs);
const char __user *filename = (char *)PT_REGS_PARM2(regs);
int flags = PT_REGS_PARM3(regs);
unsigned short mode = PT_REGS_PARM4(regs);
#else
KRETFUNC_PROBE(FNNAME, int dfd, const char __user *filename, int flags, int ret)
KRETFUNC_PROBE(FNNAME, int dfd, const char __user *filename, int flags,
unsigned short mode, int ret)
{
#endif
"""
Expand All @@ -245,13 +257,16 @@
const char __user *filename = (char *)PT_REGS_PARM2(regs);
struct open_how __user how;
int flags;
unsigned short mode;
bpf_probe_read_user(&how, sizeof(struct open_how), (struct open_how*)PT_REGS_PARM3(regs));
flags = how.flags;
mode = how.mode;
#else
KRETFUNC_PROBE(FNNAME, int dfd, const char __user *filename, struct open_how __user *how, int ret)
{
int flags = how->flags;
unsigned short mode = how->mode;
#endif
"""

Expand All @@ -278,6 +293,7 @@
data.ts = tsp / 1000;
data.uid = bpf_get_current_uid_gid();
data.flags = flags; // EXTENDED_STRUCT_MEMBER
data.mode = mode; // EXTENDED_STRUCT_MEMBER
data.ret = ret;
SUBMIT_DATA
Expand Down Expand Up @@ -406,7 +422,7 @@
print("%-6s %-16s %4s %3s " %
("TID" if args.tid else "PID", "COMM", "FD", "ERR"), end="")
if args.extended_fields:
print("%-9s" % ("FLAGS"), end="")
print("%-8s %-4s " % ("FLAGS", "MODE"), end="")
print("PATH")

class EventType(object):
Expand Down Expand Up @@ -453,7 +469,7 @@ def print_event(cpu, data, size):
event.comm, fd_s, err), nl="")

if args.extended_fields:
printb(b"%08o " % event.flags, nl="")
printb(b"%08o %04o " % (event.flags, event.mode), nl="")

if not args.full_path:
printb(b"%s" % event.name)
Expand Down
41 changes: 21 additions & 20 deletions tools/opensnoop_example.txt
Original file line number Diff line number Diff line change
Expand Up @@ -156,30 +156,31 @@ to the '-n' option.
The -e option prints out extra columns; for example, the following output
contains the flags passed to open(2), in octal:

# ./opensnoop -e
PID COMM FD ERR FLAGS PATH
28512 sshd 10 0 00101101 /proc/self/oom_score_adj
28512 sshd 3 0 02100000 /etc/ld.so.cache
28512 sshd 3 0 02100000 /lib/x86_64-linux-gnu/libwrap.so.0
28512 sshd 3 0 02100000 /lib/x86_64-linux-gnu/libaudit.so.1
28512 sshd 3 0 02100000 /lib/x86_64-linux-gnu/libpam.so.0
28512 sshd 3 0 02100000 /lib/x86_64-linux-gnu/libselinux.so.1
28512 sshd 3 0 02100000 /lib/x86_64-linux-gnu/libsystemd.so.0
28512 sshd 3 0 02100000 /usr/lib/x86_64-linux-gnu/libcrypto.so.1.0.2
28512 sshd 3 0 02100000 /lib/x86_64-linux-gnu/libutil.so.1
# ./opensnoop.py -e
PID COMM FD ERR FLAGS MODE PATH
312769 cgroupify 5 0 02204000 0000 .
312769 cgroupify 5 0 00000000 0000 312814/cgroup.procs
312769 cgroupify 5 0 00000000 0000 312749/cgroup.procs
312769 cgroupify 5 0 00000000 0000 313063/cgroup.procs
1648 abrt-dump-journ 28 0 02004000 0000 /var/log/journal/system.journal
1646 abrt-dump-journ 28 0 02004000 0000 /var/log/journal/system.journal
1325 in:imjournal 106 0 02004000 0000 /var/log/journal/system.journal
1647 abrt-dump-journ 28 0 02004000 0000 /var/log/journal/system.journal
322334 cpptools 14 0 02100000 0666 /proc/328016/status
322334 cpptools 14 0 02100000 0666 /proc/328050/status
322334 cpptools 14 0 02100000 0666 /proc/327773/status


The -f option filters based on flags to the open(2) call, for example:

# ./opensnoop -e -f O_WRONLY -f O_RDWR
PID COMM FD ERR FLAGS PATH
28084 clear_console 3 0 00100002 /dev/tty
28084 clear_console -1 13 00100002 /dev/tty0
28084 clear_console -1 13 00100001 /dev/tty0
28084 clear_console -1 13 00100002 /dev/console
28084 clear_console -1 13 00100001 /dev/console
28051 sshd 8 0 02100002 /var/run/utmp
28051 sshd 7 0 00100001 /var/log/wtmp
# ./opensnoop.py -e -f O_WRONLY -f O_RDWR
PID COMM FD ERR FLAGS MODE PATH
1325 in:imjournal 106 0 02000101 0600 /var/lib/rsyslog/imjournal.state.tmp
312749 ThreadPoolForeg 196 0 00000302 0600 /home/rongtao/Default/.com.google.Chrome.FDpC7Z
312749 ThreadPoolForeg 196 0 00000302 0600 /home/rongtao/.com.google.Chrome.AiQLoO
1580 gssproxy -1 2 00000002 0000 /proc/net/rpc/use-gss-proxy
328900 awk 3 0 00000002 0000 /dev/null
1387 ksmtuned 3 0 00001101 0666 /sys/kernel/mm/ksm/run


The --cgroupmap option filters based on a cgroup set. It is meant to be used
Expand Down

0 comments on commit 761d813

Please sign in to comment.