From: Wen Yang Date: Wed, 21 Apr 2021 08:21:56 +0000 (+0800) Subject: Tools: add the PPID/PCOMM fields in mountsnoop X-Git-Tag: v0.22.0~37 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=246450117d4f58f5f5fec7bb9b7ba2632141a63f;p=platform%2Fupstream%2Fbcc.git Tools: add the PPID/PCOMM fields in mountsnoop It is found that in the production environment, the system() function or shell command is often used to start the mount process temporarily, so the PPID/PCOMM field needs to be added to find the corresponding program. Signed-off-by: Wen Yang --- diff --git a/tools/mountsnoop.py b/tools/mountsnoop.py index 250927f5..6a0eea1e 100755 --- a/tools/mountsnoop.py +++ b/tools/mountsnoop.py @@ -75,6 +75,8 @@ struct data_t { /* current->nsproxy->mnt_ns->ns.inum */ unsigned int mnt_ns; char comm[TASK_COMM_LEN]; + char pcomm[TASK_COMM_LEN]; + pid_t ppid; unsigned long flags; } enter; /* @@ -105,6 +107,8 @@ int syscall__mount(struct pt_regs *ctx, char __user *source, bpf_get_current_comm(event.enter.comm, sizeof(event.enter.comm)); event.enter.flags = flags; task = (struct task_struct *)bpf_get_current_task(); + event.enter.ppid = task->real_parent->tgid; + bpf_probe_read_kernel_str(&event.enter.pcomm, TASK_COMM_LEN, task->real_parent->comm); nsproxy = task->nsproxy; mnt_ns = nsproxy->mnt_ns; event.enter.mnt_ns = mnt_ns->ns.inum; @@ -160,6 +164,8 @@ int syscall__umount(struct pt_regs *ctx, char __user *target, int flags) bpf_get_current_comm(event.enter.comm, sizeof(event.enter.comm)); event.enter.flags = flags; task = (struct task_struct *)bpf_get_current_task(); + event.enter.ppid = task->real_parent->tgid; + bpf_probe_read_kernel_str(&event.enter.pcomm, TASK_COMM_LEN, task->real_parent->comm); nsproxy = task->nsproxy; mnt_ns = nsproxy->mnt_ns; event.enter.mnt_ns = mnt_ns->ns.inum; @@ -246,6 +252,8 @@ class EnterData(ctypes.Structure): _fields_ = [ ('mnt_ns', ctypes.c_uint), ('comm', ctypes.c_char * TASK_COMM_LEN), + ('pcomm', ctypes.c_char * TASK_COMM_LEN), + ('ppid', ctypes.c_uint), ('flags', ctypes.c_ulong), ] @@ -333,7 +341,7 @@ else: return '"{}"'.format(''.join(escape_character(c) for c in s)) -def print_event(mounts, umounts, cpu, data, size): +def print_event(mounts, umounts, parent, cpu, data, size): event = ctypes.cast(data, ctypes.POINTER(Event)).contents try: @@ -344,6 +352,8 @@ def print_event(mounts, umounts, cpu, data, size): 'mnt_ns': event.union.enter.mnt_ns, 'comm': event.union.enter.comm, 'flags': event.union.enter.flags, + 'ppid': event.union.enter.ppid, + 'pcomm': event.union.enter.pcomm, } elif event.type == EventType.EVENT_MOUNT_SOURCE: mounts[event.pid]['source'] = event.union.str @@ -361,6 +371,8 @@ def print_event(mounts, umounts, cpu, data, size): 'mnt_ns': event.union.enter.mnt_ns, 'comm': event.union.enter.comm, 'flags': event.union.enter.flags, + 'ppid': event.union.enter.ppid, + 'pcomm': event.union.enter.pcomm, } elif event.type == EventType.EVENT_UMOUNT_TARGET: umounts[event.pid]['target'] = event.union.str @@ -382,9 +394,15 @@ def print_event(mounts, umounts, cpu, data, size): target=decode_mount_string(syscall['target']), flags=decode_umount_flags(syscall['flags']), retval=decode_errno(event.union.retval)) - print('{:16} {:<7} {:<7} {:<11} {}'.format( - syscall['comm'].decode('utf-8', 'replace'), syscall['tgid'], - syscall['pid'], syscall['mnt_ns'], call)) + if parent: + print('{:16} {:<7} {:<7} {:16} {:<7} {:<11} {}'.format( + syscall['comm'].decode('utf-8', 'replace'), syscall['tgid'], + syscall['pid'], syscall['pcomm'].decode('utf-8', 'replace'), + syscall['ppid'], syscall['mnt_ns'], call)) + else: + print('{:16} {:<7} {:<7} {:<11} {}'.format( + syscall['comm'].decode('utf-8', 'replace'), syscall['tgid'], + syscall['pid'], syscall['mnt_ns'], call)) except KeyError: # This might happen if we lost an event. pass @@ -396,6 +414,8 @@ def main(): ) parser.add_argument("--ebpf", action="store_true", help=argparse.SUPPRESS) + parser.add_argument("-P", "--parent_process", action="store_true", + help="also snoop the parent process") args = parser.parse_args() mounts = {} @@ -411,9 +431,15 @@ def main(): b.attach_kprobe(event=umount_fnname, fn_name="syscall__umount") b.attach_kretprobe(event=umount_fnname, fn_name="do_ret_sys_umount") b['events'].open_perf_buffer( - functools.partial(print_event, mounts, umounts)) - print('{:16} {:<7} {:<7} {:<11} {}'.format( - 'COMM', 'PID', 'TID', 'MNT_NS', 'CALL')) + functools.partial(print_event, mounts, umounts, args.parent_process)) + + if args.parent_process: + print('{:16} {:<7} {:<7} {:16} {:<7} {:<11} {}'.format( + 'COMM', 'PID', 'TID', 'PCOMM', 'PPID', 'MNT_NS', 'CALL')) + else: + print('{:16} {:<7} {:<7} {:<11} {}'.format( + 'COMM', 'PID', 'TID', 'MNT_NS', 'CALL')) + while True: try: b.perf_buffer_poll() diff --git a/tools/mountsnoop_example.txt b/tools/mountsnoop_example.txt index 1c5144ee..1c9a7e42 100644 --- a/tools/mountsnoop_example.txt +++ b/tools/mountsnoop_example.txt @@ -17,6 +17,11 @@ unshare 717 717 4026532160 mount("none", "/", "", MS_REC|MS_PR mount 725 725 4026532160 mount("/mnt", "/mnt", "", MS_MGC_VAL|MS_BIND, "") = 0 umount 728 728 4026532160 umount("/mnt", 0x0) = 0 +# ./mountsnoop.py -P +COMM PID TID PCOMM PPID MNT_NS CALL +mount 51526 51526 bash 49313 3222937920 mount("/mnt", "/mnt", "", MS_MGC_VAL|MS_BIND, "", "") = 0 +umount 51613 51613 bash 49313 3222937920 umount("/mnt", 0x0) = 0 + The output shows the calling command, its process ID and thread ID, the mount namespace the call was made in, and the call itself.