All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH bpf-next] bpf: emit audit messages upon successful prog load and unload
@ 2018-10-04 13:50 Daniel Borkmann
  2018-10-04 17:11 ` Alexei Starovoitov
  0 siblings, 1 reply; 16+ messages in thread
From: Daniel Borkmann @ 2018-10-04 13:50 UTC (permalink / raw)
  To: ast; +Cc: netdev, brouer, Daniel Borkmann, Jiri Olsa

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 1332
  [...]
  ----
  time->Thu Oct  4 15:29:11 2018
  type=PROCTITLE msg=audit(1538659751.047:174): proctitle=2E2F746573745F76657269666965720030
  type=SYSCALL msg=audit(1538659751.047:174): arch=c000003e syscall=321 success=yes exit=3
    a0=5 a1=7ffe6f46dec0 a2=48 a3=40bd40 items=0 ppid=1892 pid=2020 auid=1000 uid=0 gid=0
    euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=pts0 ses=3 comm="test_verifier"
    exe="/home/foo/test_verifier" key=(null)
  type=UNKNOWN[1332] msg=audit(1538659751.047:174): auid=1000 uid=0 gid=0 ses=3 pid=2020
    comm="test_verifier" exe="/home/foo/test_verifier" prog-id=2 event=LOAD
  ----
  time->Thu Oct  4 15:29:11 2018
  type=UNKNOWN[1332] msg=audit(1538659751.047:176): prog-id=2 event=UNLOAD
  ----
  [...]

Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Cc: Jiri Olsa <jolsa@kernel.org>
---
 include/linux/audit.h      |  3 +++
 include/uapi/linux/audit.h |  1 +
 kernel/auditsc.c           |  2 +-
 kernel/bpf/syscall.c       | 31 +++++++++++++++++++++++++++++++
 4 files changed, 36 insertions(+), 1 deletion(-)

diff --git a/include/linux/audit.h b/include/linux/audit.h
index 9334fbe..9495c84 100644
--- a/include/linux/audit.h
+++ b/include/linux/audit.h
@@ -152,6 +152,7 @@ extern void		    audit_log_key(struct audit_buffer *ab,
 extern void		    audit_log_link_denied(const char *operation);
 extern void		    audit_log_lost(const char *message);
 
+extern void audit_log_task(struct audit_buffer *ab);
 extern int audit_log_task_context(struct audit_buffer *ab);
 extern void audit_log_task_info(struct audit_buffer *ab,
 				struct task_struct *tsk);
@@ -198,6 +199,8 @@ static inline void audit_log_key(struct audit_buffer *ab, char *key)
 { }
 static inline void audit_log_link_denied(const char *string)
 { }
+static inline void audit_log_task(struct audit_buffer *ab)
+{ }
 static inline int audit_log_task_context(struct audit_buffer *ab)
 {
 	return 0;
diff --git a/include/uapi/linux/audit.h b/include/uapi/linux/audit.h
index 818ae69..a749881 100644
--- a/include/uapi/linux/audit.h
+++ b/include/uapi/linux/audit.h
@@ -114,6 +114,7 @@
 #define AUDIT_REPLACE		1329	/* Replace auditd if this packet unanswerd */
 #define AUDIT_KERN_MODULE	1330	/* Kernel Module events */
 #define AUDIT_FANOTIFY		1331	/* Fanotify access decision */
+#define AUDIT_BPF		1332	/* BPF subsystem */
 
 #define AUDIT_AVC		1400	/* SE Linux avc denial or grant */
 #define AUDIT_SELINUX_ERR	1401	/* Internal SE Linux Errors */
diff --git a/kernel/auditsc.c b/kernel/auditsc.c
index b2d1f04..6c498d9 100644
--- a/kernel/auditsc.c
+++ b/kernel/auditsc.c
@@ -2427,7 +2427,7 @@ void __audit_fanotify(unsigned int response)
 		AUDIT_FANOTIFY,	"resp=%u", response);
 }
 
-static void audit_log_task(struct audit_buffer *ab)
+void audit_log_task(struct audit_buffer *ab)
 {
 	kuid_t auid, uid;
 	kgid_t gid;
diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c
index 5742df2..83afbd1 100644
--- a/kernel/bpf/syscall.c
+++ b/kernel/bpf/syscall.c
@@ -31,6 +31,7 @@
 #include <linux/timekeeping.h>
 #include <linux/ctype.h>
 #include <linux/nospec.h>
+#include <linux/audit.h>
 
 #define IS_FD_ARRAY(map) ((map)->map_type == BPF_MAP_TYPE_PROG_ARRAY || \
 			   (map)->map_type == BPF_MAP_TYPE_PERF_EVENT_ARRAY || \
@@ -1011,6 +1012,34 @@ static void free_used_maps(struct bpf_prog_aux *aux)
 	kfree(aux->used_maps);
 }
 
+enum bpf_event {
+	BPF_EVENT_LOAD,
+	BPF_EVENT_UNLOAD,
+};
+
+static const char * const bpf_event_audit_str[] = {
+	[BPF_EVENT_LOAD]   = "LOAD",
+	[BPF_EVENT_UNLOAD] = "UNLOAD",
+};
+
+static void bpf_audit_prog(const struct bpf_prog *prog, enum bpf_event event)
+{
+	bool has_task_context = event == BPF_EVENT_LOAD;
+	struct audit_buffer *ab;
+
+	if (audit_enabled == AUDIT_OFF)
+		return;
+	ab = audit_log_start(audit_context(), GFP_ATOMIC, AUDIT_BPF);
+	if (unlikely(!ab))
+		return;
+	if (has_task_context)
+		audit_log_task(ab);
+	audit_log_format(ab, "%sprog-id=%u event=%s",
+			 has_task_context ? " " : "",
+			 prog->aux->id, bpf_event_audit_str[event]);
+	audit_log_end(ab);
+}
+
 int __bpf_prog_charge(struct user_struct *user, u32 pages)
 {
 	unsigned long memlock_limit = rlimit(RLIMIT_MEMLOCK) >> PAGE_SHIFT;
@@ -1112,6 +1141,7 @@ static void __bpf_prog_put_rcu(struct rcu_head *rcu)
 static void __bpf_prog_put(struct bpf_prog *prog, bool do_idr_lock)
 {
 	if (atomic_dec_and_test(&prog->aux->refcnt)) {
+		bpf_audit_prog(prog, BPF_EVENT_UNLOAD);
 		/* bpf_prog_free_id() must be called first */
 		bpf_prog_free_id(prog, do_idr_lock);
 		bpf_prog_kallsyms_del_all(prog);
@@ -1452,6 +1482,7 @@ static int bpf_prog_load(union bpf_attr *attr)
 	}
 
 	bpf_prog_kallsyms_add(prog);
+	bpf_audit_prog(prog, BPF_EVENT_LOAD);
 	return err;
 
 free_used_maps:
-- 
2.9.5

^ permalink raw reply related	[flat|nested] 16+ messages in thread

end of thread, other threads:[~2018-10-19  6:12 UTC | newest]

Thread overview: 16+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-10-04 13:50 [PATCH bpf-next] bpf: emit audit messages upon successful prog load and unload Daniel Borkmann
2018-10-04 17:11 ` Alexei Starovoitov
2018-10-04 18:39   ` Jesper Dangaard Brouer
2018-10-04 19:41     ` Daniel Borkmann
2018-10-04 20:22       ` Jesper Dangaard Brouer
2018-10-04 22:10         ` Alexei Starovoitov
2018-10-05  6:14           ` Jiri Olsa
2018-10-05 18:44             ` Alexei Starovoitov
2018-10-05 19:42               ` Arnaldo Carvalho de Melo
2018-10-05 20:26                 ` Alexei Starovoitov
2018-10-05 22:05               ` Jiri Olsa
2018-10-07 16:19                 ` Jesper Dangaard Brouer
2018-10-18 19:53                   ` Richard Guy Briggs
2018-10-18 22:09                     ` Steve Grubb
2018-10-08 11:57           ` Jiri Olsa
2018-10-10 19:53             ` Alexei Starovoitov

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.