Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add modify_random, passing randomness (LTO) test #4

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions bpf/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,10 @@ make

`modify_file_name` intercepts `openat` syscall to modify the names of read program files suffixed with ".c", ".cc", ".cpp" or ".cxx" to empty, making `__FILE__` macro return a fixed value.

## `modify_random`

`modify_random` intercepts the reading syscalls of `/dev/random` and `/dev/urandom`, and `getrandom` syscall, making the random generation of names in the compiler (e.g. random names in Link Time Optimization) fixed.

## `preload_filter`

`preload_filter` intercepts the reading syscalls of `/etc/ld.so.preload` when loading an executable file. The reading syscalls return origin content of `/etc/ld.so.preload` when the specified processes calling them, or they return empty content.
3 changes: 2 additions & 1 deletion bpf/src/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@
/preload_filter
/modify_file_timestamp
/modify_file_name
/modify_file_read
/modify_file_read
/modify_random
2 changes: 1 addition & 1 deletion bpf/src/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ INCLUDES := -I$(OUTPUT) -I../libbpf/include/uapi -I$(dir $(VMLINUX))
CFLAGS := -g -Wall
ALL_LDFLAGS := $(LDFLAGS) $(EXTRA_LDFLAGS)

APPS = modify_time preload_filter modify_file_timestamp modify_file_name modify_file_read
APPS = modify_time preload_filter modify_file_timestamp modify_file_name modify_file_read modify_random

# Get Clang's default includes on this system. We'll explicitly add these dirs
# to the includes list when compiling with `-target bpf` because otherwise some
Expand Down
22 changes: 18 additions & 4 deletions bpf/src/common.bpf.h
Original file line number Diff line number Diff line change
@@ -1,7 +1,21 @@

bool comm_filter(char *comm) {
if (!(__builtin_memcmp("cc1\0", comm, 4) == 0)) {
return 0;
__inline__ __attribute__((always_inline)) bool comm_filter(char *comm) {
if ((__builtin_memcmp("cc1\0", comm, 4) == 0)) {
return 1;
}
return 1;
if ((__builtin_memcmp("cc1p", comm, 4) == 0) &&
(__builtin_memcmp("lus\0", comm + 4, 4) == 0)) {
return 1;
}
if ((__builtin_memcmp("lto1", comm, 4) == 0) &&
(__builtin_memcmp("-wpa", comm + 4, 4) == 0)) {
return 1;
}
if ((__builtin_memcmp("g++\0", comm, 4) == 0)) {
return 1;
}
if ((__builtin_memcmp("gcc\0", comm, 4) == 0)) {
return 1;
}
return 0;
}
9 changes: 7 additions & 2 deletions bpf/src/modify_file_read.bpf.c
Original file line number Diff line number Diff line change
Expand Up @@ -142,14 +142,19 @@ int handle_exit_newfstatat(struct trace_event_raw_sys_exit *ctx) {

SEC("tracepoint/syscalls/sys_enter_read")
int handle_enter_read(struct trace_event_raw_sys_enter *ctx) {
tid_t tid = bpf_get_current_pid_tgid();

char comm[16];
bpf_get_current_comm(comm, 16);
if (!comm_filter(comm)) {
return 0;
}

tid_t tid = bpf_get_current_pid_tgid();

long unsigned int *blank_p = bpf_map_lookup_elem(&tids, &tid);
if (blank_p == NULL) {
return 0;
}

char *content_p = (void *)ctx->args[1];

bpf_map_update_elem(&content_ps, &tid, &content_p, BPF_ANY);
Expand Down
180 changes: 180 additions & 0 deletions bpf/src/modify_random.bpf.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,180 @@
#include "vmlinux.h"
#include <bpf/bpf_helpers.h>
#include <bpf/bpf_tracing.h>
#include <bpf/bpf_core_read.h>
#include "modify_file_read.h"
#include "common.bpf.h"
#include "../../config/time_config.h"

char LICENSE[] SEC("license") = "Dual BSD/GPL";

char random_name[] = "/dev/random";
char urandom_name[] = "/dev/urandom";
char replace_buf[] = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0";

struct read_prop {
void *buf;
size_t count;
};

struct {
__uint(type, BPF_MAP_TYPE_RINGBUF);
__uint(max_entries, 256 * 1024);
} rb SEC(".maps");

struct {
__uint(type, BPF_MAP_TYPE_HASH);
__uint(max_entries, 8192);
__type(key, tid_t);
__type(value, u8);
} tids SEC(".maps");

struct {
__uint(type, BPF_MAP_TYPE_HASH);
__uint(max_entries, 8192);
__type(key, tid_t);
__type(value, struct read_prop);
} read_props SEC(".maps");

struct {
__uint(type, BPF_MAP_TYPE_HASH);
__uint(max_entries, 8192);
__type(key, tid_t);
__type(value, u64);
} random_bufs SEC(".maps");

SEC("tracepoint/syscalls/sys_enter_openat")
int handle_enter_openat(struct trace_event_raw_sys_enter *ctx) {
tid_t tid = bpf_get_current_pid_tgid();

char comm[16];
bpf_get_current_comm(comm, 16);

if (!comm_filter(comm)) {
return 0;
}

char *filename_p = (char *)ctx->args[1];

char filename[20];
long success = bpf_probe_read_user(filename, 20, filename_p);

if (((__builtin_memcmp(random_name, filename, 4) == 0) &&
(__builtin_memcmp(random_name + 4, filename + 4, 4) == 0) &&
(random_name[9] == filename[9] && random_name[10] == filename[10] &&
random_name[11] == filename[11]))) {
bpf_printk("[sys_enter_openat] Detected reading %s", filename);

u8 blank = 0;
bpf_map_update_elem(&tids, &tid, &blank, BPF_ANY);
}

if (((__builtin_memcmp(urandom_name, filename, 4) == 0) &&
(__builtin_memcmp(urandom_name + 4, filename + 4, 4) == 0) &&
(__builtin_memcmp(urandom_name + 8, filename + 8, 4) == 0))) {
bpf_printk("[sys_enter_openat] Detected reading %s", filename);

u8 blank = 0;
bpf_map_update_elem(&tids, &tid, &blank, BPF_ANY);
}

return 0;
}

SEC("tracepoint/syscalls/sys_enter_read")
int handle_enter_read(struct trace_event_raw_sys_enter *ctx) {
char comm[16];
bpf_get_current_comm(comm, 16);
if (!comm_filter(comm)) {
return 0;
}

tid_t tid = bpf_get_current_pid_tgid();

long unsigned int *blank_p = bpf_map_lookup_elem(&tids, &tid);
if (blank_p == NULL) {
return 0;
}

struct read_prop a_read_prop;
a_read_prop.buf = (void *)ctx->args[1];
a_read_prop.count = (size_t)ctx->args[2];

bpf_map_update_elem(&read_props, &tid, &a_read_prop, BPF_ANY);

return 0;
}

SEC("tracepoint/syscalls/sys_exit_read")
int handle_exit_read(struct trace_event_raw_sys_exit *ctx) {
char comm[16];
bpf_get_current_comm(comm, 16);
if (!comm_filter(comm)) {
return 0;
}

tid_t tid = bpf_get_current_pid_tgid();

long unsigned int *blank_p = bpf_map_lookup_elem(&tids, &tid);
if (blank_p == NULL) {
return 0;
}
bpf_map_delete_elem(&tids, &tid);

long unsigned int *a_read_prop_p = bpf_map_lookup_elem(&read_props, &tid);
if (a_read_prop_p == NULL) {
return 0;
}

struct read_prop a_read_prop = *(struct read_prop *)a_read_prop_p;

bpf_printk("[sys_exit_read] OVERWRITING read buf at %p size %d to 0",
a_read_prop.buf, a_read_prop.count);
bool success = bpf_probe_write_user(a_read_prop.buf, replace_buf, 8);
bpf_printk("[sys_exit_read] RESULT %d", success);

return 0;
}

SEC("tracepoint/syscalls/sys_enter_getrandom")
int handle_enter_getrandom(struct trace_event_raw_sys_enter *ctx) {
char comm[16];
bpf_get_current_comm(comm, 16);

if (!comm_filter(comm)) {
return 0;
}

tid_t tid = bpf_get_current_pid_tgid();

void *random_buf = (void *)ctx->args[0];
bpf_map_update_elem(&random_bufs, &tid, &random_buf, BPF_ANY);

return 0;
}

SEC("tracepoint/syscalls/sys_exit_getrandom")
int handle_exit_getrandom(struct trace_event_raw_sys_exit *ctx) {
char comm[16];
bpf_get_current_comm(comm, 16);
if (!comm_filter(comm)) {
return 0;
}

tid_t tid = bpf_get_current_pid_tgid();

long unsigned int *random_buf_p = bpf_map_lookup_elem(&random_bufs, &tid);
if (random_buf_p == NULL) {
return 0;
}
bpf_map_delete_elem(&random_bufs, &tid);

char *random_buf = (char *)*random_buf_p;

bpf_printk("[sys_exit_getrandom] OVERWRITING random buf at %p size 8 to 0",
random_buf);
bool success = bpf_probe_write_user(random_buf, replace_buf, 8);
bpf_printk("[sys_exit_getrandom] RESULT %d", success);

return 0;
}
Loading