-
Notifications
You must be signed in to change notification settings - Fork 384
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
bpf: Add lsm.s/* bpf programs for IMA hash collection
Due to restrictions of bpf sleepable programs (no tailcalls, no perf buffer and per_cpu maps, etc.), we need to split generic LSM sensor into three parts (collections) and load them in this order: - bpf_generic_output sends event using perf buffer - bpf_generic_lsm_ima_* calculates hash using IMA helpers - bpf_generic_lsm_core does everything else Signed-off-by: Andrei Fedotov <[email protected]>
- Loading branch information
1 parent
4475918
commit 109f288
Showing
11 changed files
with
317 additions
and
22 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) | ||
/* Copyright Authors of Cilium */ | ||
|
||
#include "vmlinux.h" | ||
#include "api.h" | ||
|
||
#define GENERIC_LSM | ||
|
||
#include "compiler.h" | ||
#include "bpf_event.h" | ||
#include "bpf_task.h" | ||
#include "retprobe_map.h" | ||
#include "types/basic.h" | ||
|
||
char _license[] __attribute__((section("license"), used)) = "Dual BSD/GPL"; | ||
|
||
struct filter_map_value { | ||
unsigned char buf[FILTER_SIZE]; | ||
}; | ||
|
||
struct { | ||
__uint(type, BPF_MAP_TYPE_ARRAY); | ||
__uint(max_entries, 1); | ||
__type(key, int); | ||
__type(value, struct filter_map_value); | ||
} filter_map SEC(".maps"); | ||
|
||
struct { | ||
__uint(type, BPF_MAP_TYPE_ARRAY); | ||
__uint(max_entries, 1); | ||
__type(key, __u32); | ||
__type(value, struct event_config); | ||
} config_map SEC(".maps"); | ||
|
||
struct { | ||
__uint(type, BPF_MAP_TYPE_HASH); | ||
__uint(max_entries, 1024); | ||
__type(key, __u64); | ||
__type(value, char[65]); | ||
} ima_hash_map SEC(".maps"); | ||
|
||
__attribute__((section("lsm.s/generic_lsm_ima_bprm"), used)) int | ||
BPF_PROG(ima_bprm, struct linux_binprm *bprm) | ||
{ | ||
char hash[65]; | ||
__u64 pid_tgid = get_current_pid_tgid(); | ||
char *dummy = map_lookup_elem(&ima_hash_map, &pid_tgid); | ||
|
||
if (dummy) { | ||
#ifdef __V61_BPF_PROG | ||
hash[0] = ima_file_hash(bprm->file, &hash[1], 64); | ||
#else | ||
hash[0] = ima_inode_hash(bprm->file->f_inode, &hash[1], 64); | ||
#endif | ||
map_update_elem(&ima_hash_map, &pid_tgid, &hash, BPF_ANY); | ||
} | ||
return 0; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) | ||
/* Copyright Authors of Cilium */ | ||
|
||
#include "vmlinux.h" | ||
#include "api.h" | ||
|
||
#define GENERIC_LSM | ||
|
||
#include "compiler.h" | ||
#include "bpf_event.h" | ||
#include "bpf_task.h" | ||
#include "retprobe_map.h" | ||
#include "types/basic.h" | ||
|
||
char _license[] __attribute__((section("license"), used)) = "Dual BSD/GPL"; | ||
|
||
struct filter_map_value { | ||
unsigned char buf[FILTER_SIZE]; | ||
}; | ||
|
||
struct { | ||
__uint(type, BPF_MAP_TYPE_ARRAY); | ||
__uint(max_entries, 1); | ||
__type(key, int); | ||
__type(value, struct filter_map_value); | ||
} filter_map SEC(".maps"); | ||
|
||
struct { | ||
__uint(type, BPF_MAP_TYPE_ARRAY); | ||
__uint(max_entries, 1); | ||
__type(key, __u32); | ||
__type(value, struct event_config); | ||
} config_map SEC(".maps"); | ||
|
||
struct { | ||
__uint(type, BPF_MAP_TYPE_HASH); | ||
__uint(max_entries, 1024); | ||
__type(key, __u64); | ||
__type(value, char[65]); | ||
} ima_hash_map SEC(".maps"); | ||
|
||
__attribute__((section("lsm.s/generic_lsm_ima_file"), used)) int | ||
BPF_PROG(ima_file, struct file *file) | ||
{ | ||
char hash[65]; | ||
__u64 pid_tgid = get_current_pid_tgid(); | ||
char *dummy = map_lookup_elem(&ima_hash_map, &pid_tgid); | ||
|
||
if (dummy) { | ||
#ifdef __V61_BPF_PROG | ||
hash[0] = ima_file_hash(file, &hash[1], 64); | ||
#else | ||
hash[0] = ima_inode_hash(file->f_inode, &hash[1], 64); | ||
#endif | ||
map_update_elem(&ima_hash_map, &pid_tgid, &hash, BPF_ANY); | ||
} | ||
return 0; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,99 @@ | ||
// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) | ||
/* Copyright Authors of Cilium */ | ||
|
||
#include "vmlinux.h" | ||
#include "api.h" | ||
|
||
#define GENERIC_LSM | ||
|
||
#include "compiler.h" | ||
#include "bpf_event.h" | ||
#include "bpf_task.h" | ||
#include "retprobe_map.h" | ||
#include "types/basic.h" | ||
|
||
char _license[] __attribute__((section("license"), used)) = "Dual BSD/GPL"; | ||
|
||
struct { | ||
__uint(type, BPF_MAP_TYPE_PERCPU_ARRAY); | ||
__uint(max_entries, 1); | ||
__type(key, __u32); | ||
__type(value, struct msg_generic_kprobe); | ||
} process_call_heap SEC(".maps"); | ||
|
||
struct { | ||
__uint(type, BPF_MAP_TYPE_HASH); | ||
__uint(max_entries, 32768); | ||
__type(key, __u64); | ||
__type(value, __s32); | ||
} override_tasks SEC(".maps"); | ||
|
||
struct filter_map_value { | ||
unsigned char buf[FILTER_SIZE]; | ||
}; | ||
|
||
/* Arrays of size 1 will be rewritten to direct loads in verifier */ | ||
struct { | ||
__uint(type, BPF_MAP_TYPE_ARRAY); | ||
__uint(max_entries, 1); | ||
__type(key, int); | ||
__type(value, struct filter_map_value); | ||
} filter_map SEC(".maps"); | ||
|
||
struct { | ||
__uint(type, BPF_MAP_TYPE_ARRAY); | ||
__uint(max_entries, 1); | ||
__type(key, __u32); | ||
__type(value, struct event_config); | ||
} config_map SEC(".maps"); | ||
|
||
#ifdef __LARGE_MAP_KEYS | ||
struct { | ||
__uint(type, BPF_MAP_TYPE_HASH); | ||
__uint(max_entries, 1024); | ||
__type(key, __u64); | ||
__type(value, char[65]); | ||
} ima_hash_map SEC(".maps"); | ||
#endif | ||
|
||
FUNC_INLINE int try_override(void *ctx) | ||
{ | ||
__u64 id = get_current_pid_tgid(); | ||
__s32 *error; | ||
|
||
error = map_lookup_elem(&override_tasks, &id); | ||
if (!error) | ||
return 0; | ||
|
||
map_delete_elem(&override_tasks, &id); | ||
return (long)*error; | ||
} | ||
|
||
__attribute__((section("lsm/generic_lsm_output"), used)) int | ||
generic_lsm_output(void *ctx) | ||
{ | ||
struct msg_generic_kprobe *e; | ||
int zero = 0; | ||
|
||
e = map_lookup_elem(&process_call_heap, &zero); | ||
if (!e) | ||
return 0; | ||
#ifdef __LARGE_MAP_KEYS | ||
if (e && e->common.flags & MSG_COMMON_FLAG_IMA_HASH) { | ||
__u64 pid_tgid = get_current_pid_tgid(); | ||
char *hash = map_lookup_elem(&ima_hash_map, &pid_tgid); | ||
|
||
if (hash) { | ||
// Copy hash after all arguments | ||
if (e->common.size + 65 <= 16383) { | ||
probe_read(&e->args[e->common.size & 16383], 65, hash); | ||
e->common.size += 65; | ||
} | ||
map_delete_elem(&ima_hash_map, &pid_tgid); | ||
} | ||
} | ||
#endif | ||
if (e->post) | ||
generic_output(ctx, (struct bpf_map_def *)&process_call_heap, MSG_OP_GENERIC_LSM); | ||
return try_override(ctx); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.