podman

Форк
0
/
podmansnoop 
173 строки · 4.2 Кб
1
#!/usr/bin/env python
2
from __future__ import print_function
3

4
# Based on the `exitsnoop` script at https://github.com/iovisor/bcc/blob/master/tools/exitsnoop.py
5
# Based on the `execsnoop` script at https://github.com/iovisor/bcc/blob/master/tools/execsnoop.py
6

7
import argparse
8
import os
9
import platform
10
import re
11
import signal
12
import sys
13

14
from bcc import BPF
15
from collections import defaultdict
16
from datetime import datetime
17
from time import strftime
18

19
bpf_src = """
20
#include <uapi/linux/ptrace.h>
21
#include <linux/sched.h>
22

23
#define ARGSIZE 128
24
#define MAXARG  19
25

26
struct data_t {
27
    u8 isArgv;
28
    u64 start_time;
29
    u64 exit_time;
30
    u32 pid;
31
    u32 ppid;
32
    char comm[TASK_COMM_LEN];
33
    char argv[ARGSIZE];
34
};
35

36
BPF_PERF_OUTPUT(events);
37

38
TRACEPOINT_PROBE(sched, sched_process_exit)
39
{
40
    struct task_struct *task = (typeof(task))bpf_get_current_task();
41
    if (task->pid != task->tgid) { return 0; }
42

43
    struct data_t data = {};
44

45
    data.start_time = task->start_time,
46
    data.exit_time = bpf_ktime_get_ns(),
47
    data.pid = task->pid,
48
    data.ppid = task->real_parent->tgid,
49
    bpf_get_current_comm(&data.comm, sizeof(data.comm));
50

51
    events.perf_submit(args, &data, sizeof(data));
52
    return 0;
53
}
54

55
static int __submit_arg(struct pt_regs *ctx, void *ptr, struct data_t *data)
56
{
57
    bpf_probe_read_user(data->argv, sizeof(data->argv), ptr);
58
    events.perf_submit(ctx, data, sizeof(struct data_t));
59
    return 1;
60
}
61

62
static int submit_arg(struct pt_regs *ctx, void *ptr, struct data_t *data)
63
{
64
    const char *argp = NULL;
65
    bpf_probe_read_user(&argp, sizeof(argp), ptr);
66
    if (argp) {
67
        return __submit_arg(ctx, (void *)(argp), data);
68
    }
69
    return 0;
70
}
71

72
int syscall__execve(struct pt_regs *ctx,
73
    const char __user *filename,
74
    const char __user *const __user *__argv,
75
    const char __user *const __user *__envp)
76
{
77

78
    struct task_struct *task = (typeof(task))bpf_get_current_task();
79

80
    struct data_t data = {};
81
    data.pid = bpf_get_current_pid_tgid() >> 32;
82
    data.isArgv = 1;
83

84
    bpf_get_current_comm(&data.comm, sizeof(data.comm));
85
    __submit_arg(ctx, (void *)filename, &data);
86

87
    // skip first arg, as we submitted filename
88
    #pragma unroll
89
    for (int i = 1; i < MAXARG; i++) {
90
        if (submit_arg(ctx, (void *)&__argv[i], &data) == 0)
91
             goto out;
92
    }
93

94
    // handle truncated argument list
95
    char ellipsis[] = "...";
96
    __submit_arg(ctx, (void *)ellipsis, &data);
97
out:
98

99
    return 0;
100
}
101

102
int do_ret_sys_execve(struct pt_regs *ctx)
103
{
104
    struct task_struct *task = (typeof(task))bpf_get_current_task();
105

106
    struct data_t data = {};
107
    data.pid = bpf_get_current_pid_tgid() >> 32;
108
    bpf_get_current_comm(&data.comm, sizeof(data.comm));
109
    events.perf_submit(ctx, &data, sizeof(data));
110
    return 0;
111
}
112
"""
113

114
def _print_header():
115
    print("%-16s %-7s %-7s %-7s %s" %
116
              ("PCOMM", "PID", "PPID", "AGE(ms)", "ARGV"))
117

118
buffer = None
119
pidToArgv = defaultdict(list)
120

121
def _print_event(cpu, data, size): # callback
122
    """Print the exit event."""
123
    global buffer
124
    e = buffer["events"].event(data)
125

126
    comm = e.comm.decode()
127
    if comm == "3":
128
        # For absolutely unknown reasons, 'crun' appears as '3'.
129
        comm = "crun"
130

131
    if e.isArgv:
132
        pidToArgv[e.pid].append(e.argv)
133
        return
134

135
    if comm not in ["podman", "crun", "runc", "conmon", "netavark", "aardvark-dns"]:
136
        try:
137
            del(pidToArgv[e.pid])
138
        except Exception:
139
            pass
140
        return
141

142
    age = (e.exit_time - e.start_time) / 1e6
143
    argv = b' '.join(pidToArgv[e.pid]).replace(b'\n', b'\\n')
144
    print("%-16s %-7d %-7d %-7.2f %s" %
145
              (comm, e.pid, e.ppid, age, argv.decode()), end="")
146
    print()
147

148
    try:
149
        del(pidToArgv[e.pid])
150
    except Exception:
151
        pass
152

153
def snoop(bpf, event_handler):
154
    bpf["events"].open_perf_buffer(event_handler)
155
    while True:
156
        bpf.perf_buffer_poll()
157

158
def main():
159
    global buffer
160
    try:
161
        buffer = BPF(text=bpf_src)
162
        execve_fnname = buffer.get_syscall_fnname("execve")
163
        buffer.attach_kprobe(event=execve_fnname, fn_name="syscall__execve")
164
        _print_header()
165
        snoop(buffer, _print_event)
166
    except KeyboardInterrupt:
167
        print()
168
        sys.exit()
169

170
    return 0
171

172
if __name__ == '__main__':
173
    main()
174

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.