Skip to content

Commit 91e6015

Browse files
borkmannAlexei Starovoitov
authored andcommitted
bpf: Emit audit messages upon successful prog load and unload
Allow for audit messages to be emitted upon BPF program load and unload for having a timeline of events. The load itself is in syscall context, so additional info about the process initiating the BPF prog creation can be logged and later directly correlated to the unload event. The only info really needed from BPF side is the globally unique prog ID where then audit user space tooling can query / dump all info needed about the specific BPF program right upon load event and enrich the record, thus these changes needed here can be kept small and non-intrusive to the core. Raw example output: # auditctl -D # auditctl -a always,exit -F arch=x86_64 -S bpf # ausearch --start recent -m 1334 [...] ---- time->Wed Nov 20 12:45:51 2019 type=PROCTITLE msg=audit(1574271951.590:8974): proctitle="./test_verifier" type=SYSCALL msg=audit(1574271951.590:8974): arch=c000003e syscall=321 success=yes exit=14 a0=5 a1=7ffe2d923e80 a2=78 a3=0 items=0 ppid=742 pid=949 auid=0 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=pts0 ses=2 comm="test_verifier" exe="/root/bpf-next/tools/testing/selftests/bpf/test_verifier" subj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 key=(null) type=UNKNOWN[1334] msg=audit(1574271951.590:8974): auid=0 uid=0 gid=0 ses=2 subj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 pid=949 comm="test_verifier" exe="/root/bpf-next/tools/testing/selftests/bpf/test_verifier" prog-id=3260 event=LOAD ---- time->Wed Nov 20 12:45:51 2019 type=UNKNOWN[1334] msg=audit(1574271951.590:8975): prog-id=3260 event=UNLOAD ---- [...] Signed-off-by: Daniel Borkmann <[email protected]> Signed-off-by: Jiri Olsa <[email protected]> Signed-off-by: Alexei Starovoitov <[email protected]> Link: https://lore.kernel.org/bpf/[email protected]
1 parent b2e2f0e commit 91e6015

File tree

4 files changed

+36
-1
lines changed

4 files changed

+36
-1
lines changed

include/linux/audit.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,7 @@ extern void audit_log_key(struct audit_buffer *ab,
159159
extern void audit_log_link_denied(const char *operation);
160160
extern void audit_log_lost(const char *message);
161161

162+
extern void audit_log_task(struct audit_buffer *ab);
162163
extern int audit_log_task_context(struct audit_buffer *ab);
163164
extern void audit_log_task_info(struct audit_buffer *ab);
164165

@@ -219,6 +220,8 @@ static inline void audit_log_key(struct audit_buffer *ab, char *key)
219220
{ }
220221
static inline void audit_log_link_denied(const char *string)
221222
{ }
223+
static inline void audit_log_task(struct audit_buffer *ab)
224+
{ }
222225
static inline int audit_log_task_context(struct audit_buffer *ab)
223226
{
224227
return 0;

include/uapi/linux/audit.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,7 @@
116116
#define AUDIT_FANOTIFY 1331 /* Fanotify access decision */
117117
#define AUDIT_TIME_INJOFFSET 1332 /* Timekeeping offset injected */
118118
#define AUDIT_TIME_ADJNTPVAL 1333 /* NTP value adjustment */
119+
#define AUDIT_BPF 1334 /* BPF subsystem */
119120

120121
#define AUDIT_AVC 1400 /* SE Linux avc denial or grant */
121122
#define AUDIT_SELINUX_ERR 1401 /* Internal SE Linux Errors */

kernel/auditsc.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2545,7 +2545,7 @@ void __audit_ntp_log(const struct audit_ntp_data *ad)
25452545
audit_log_ntp_val(ad, "adjust", AUDIT_NTP_ADJUST);
25462546
}
25472547

2548-
static void audit_log_task(struct audit_buffer *ab)
2548+
void audit_log_task(struct audit_buffer *ab)
25492549
{
25502550
kuid_t auid, uid;
25512551
kgid_t gid;

kernel/bpf/syscall.c

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#include <linux/timekeeping.h>
2424
#include <linux/ctype.h>
2525
#include <linux/nospec.h>
26+
#include <linux/audit.h>
2627
#include <uapi/linux/btf.h>
2728

2829
#define IS_FD_ARRAY(map) ((map)->map_type == BPF_MAP_TYPE_PROG_ARRAY || \
@@ -1318,6 +1319,34 @@ static void free_used_maps(struct bpf_prog_aux *aux)
13181319
kfree(aux->used_maps);
13191320
}
13201321

1322+
enum bpf_event {
1323+
BPF_EVENT_LOAD,
1324+
BPF_EVENT_UNLOAD,
1325+
};
1326+
1327+
static const char * const bpf_event_audit_str[] = {
1328+
[BPF_EVENT_LOAD] = "LOAD",
1329+
[BPF_EVENT_UNLOAD] = "UNLOAD",
1330+
};
1331+
1332+
static void bpf_audit_prog(const struct bpf_prog *prog, enum bpf_event event)
1333+
{
1334+
bool has_task_context = event == BPF_EVENT_LOAD;
1335+
struct audit_buffer *ab;
1336+
1337+
if (audit_enabled == AUDIT_OFF)
1338+
return;
1339+
ab = audit_log_start(audit_context(), GFP_ATOMIC, AUDIT_BPF);
1340+
if (unlikely(!ab))
1341+
return;
1342+
if (has_task_context)
1343+
audit_log_task(ab);
1344+
audit_log_format(ab, "%sprog-id=%u event=%s",
1345+
has_task_context ? " " : "",
1346+
prog->aux->id, bpf_event_audit_str[event]);
1347+
audit_log_end(ab);
1348+
}
1349+
13211350
int __bpf_prog_charge(struct user_struct *user, u32 pages)
13221351
{
13231352
unsigned long memlock_limit = rlimit(RLIMIT_MEMLOCK) >> PAGE_SHIFT;
@@ -1434,6 +1463,7 @@ static void __bpf_prog_put(struct bpf_prog *prog, bool do_idr_lock)
14341463
{
14351464
if (atomic64_dec_and_test(&prog->aux->refcnt)) {
14361465
perf_event_bpf_event(prog, PERF_BPF_EVENT_PROG_UNLOAD, 0);
1466+
bpf_audit_prog(prog, BPF_EVENT_UNLOAD);
14371467
/* bpf_prog_free_id() must be called first */
14381468
bpf_prog_free_id(prog, do_idr_lock);
14391469
__bpf_prog_put_noref(prog, true);
@@ -1843,6 +1873,7 @@ static int bpf_prog_load(union bpf_attr *attr, union bpf_attr __user *uattr)
18431873
*/
18441874
bpf_prog_kallsyms_add(prog);
18451875
perf_event_bpf_event(prog, PERF_BPF_EVENT_PROG_LOAD, 0);
1876+
bpf_audit_prog(prog, BPF_EVENT_LOAD);
18461877

18471878
err = bpf_prog_new_fd(prog);
18481879
if (err < 0)

0 commit comments

Comments
 (0)