Added more communication utils between userspace and kernel:

* Included maps and kernel ring buffer communication
* Extended the ebpf structure to include more modules
* New utils in both user and kernelspace
* Other changes
* This update precedes a great effort on researching and learning and linux kernel tracing and studing ebpfkit from defcon. More functionalities should come rather quickly now.
This commit is contained in:
h3xduck
2021-12-29 14:44:09 -05:00
parent 510fc89de0
commit d5478ed7a0
12 changed files with 1014 additions and 793 deletions

Binary file not shown.

Binary file not shown.

File diff suppressed because it is too large Load Diff

Binary file not shown.

View File

@@ -9,7 +9,7 @@
#include <netdb.h>
#include <stdlib.h>
#include "../constants/constants.h"
#include "../common/constants.h"
// For printing with colors
#define KGRN "\x1B[32m"

36
src/common/map_defs.h Normal file
View File

@@ -0,0 +1,36 @@
#ifndef __MAP_DEFS_H
#define __MAP_DEFS_H
#define RB_EVENT_MAX_MESSAGE_SIZE 512
typedef enum {
INFO,
DEBUG,
EXIT,
ERROR
} event_type_t;
struct rb_event {
int pid;
char message[RB_EVENT_MAX_MESSAGE_SIZE];
int code;
event_type_t event_type;
};
//sched_process_exec tracepoint contents
struct trace_entry {
short unsigned int type;
unsigned char flags;
unsigned char preempt_count;
int pid;
};
struct trace_event_raw_sched_process_exec {
struct trace_entry ent;
unsigned int __data_loc_filename;
int pid;
int old_pid;
char __data[0];
};
#endif

68
src/ebpf/include/bpf/fs.h Normal file
View File

@@ -0,0 +1,68 @@
#ifndef __FS_H
#define __FS_H
#include <stdio.h>
#include <linux/types.h>
#include <unistd.h>
#include <string.h>
#include <linux/bpf.h>
#include <bpf/bpf_helpers.h>
#include <bpf/bpf_tracing.h>
#include <bpf/bpf_core_read.h>
#include "../common/constants.h"
#include "../common/map_defs.h"
#define RING_BUFFER_MAX_ELEMS 256
//Ring buffer - For communication ebpf -> userspace
struct {
__uint(type, BPF_MAP_TYPE_RINGBUF);
__uint(max_entries, RING_BUFFER_MAX_ELEMS * 1024); //Multiple struct rb_event(s) must fit here
} rb_comm SEC(".maps");
//BPF map
/*struct {
__uint(type, BPF_MAP_TYPE_HASH);
__uint(max_entries, 8192);
__type(key, pid_t);
__type(value, char[5]);
} exec_start SEC(".maps");*/
/**
* @brief A kthread is started in the kernel (a new program)
* @ref https://elixir.bootlin.com/linux/latest/source/include/trace/events/sched.h#L397
*/
SEC("tp/sched/sched_process_exec")
int handle_exec(struct trace_event_raw_sched_process_exec *ctx){
struct task_struct *task;
unsigned fname_off;
struct rb_event *e;
pid_t pid;
int ts;
pid = bpf_get_current_pid_tgid() >> 32;
ts = bpf_ktime_get_ns();
/* reserve sample from BPF ringbuf */
e = bpf_ringbuf_reserve(&rb_comm, sizeof(*e), 0);
if (!e){
return 0;
}
e->pid = pid;
e->event_type = INFO;
e->code = 0;
char* message = "HOLA\0";
bpf_probe_read_str(&e->message, sizeof(message), message);
/* successfully submit it to user-space for post-processing */
bpf_ringbuf_submit(e, 0);
return 0;
}
#endif

View File

@@ -1,4 +1,4 @@
//#include "newvmlinux.h"
//Linux system includes
#include <unistd.h>
#include <stdbool.h>
#include <linux/tcp.h>
@@ -15,36 +15,27 @@
#include <linux/ip.h>
#include <linux/udp.h>
//BPF & libbpf dependencies
#include <linux/bpf.h>
#include <bpf/bpf_helpers.h>
#include <bpf/bpf_tracing.h>
#include <bpf/bpf_core_read.h>
//User-kernel dependencies
#include "../user/include/xdp_filter.h"
#include "../constants/constants.h"
#include "../common/constants.h"
//BPF exclusive includes
#include "packet/packet_manager.h"
#include "packet/protocol/tcp_helper.h"
#include "xdp/xdp_helper.h"
#include "common/common_utils.h"
//BPF modules to load
#include "include/bpf/fs.h"
char LICENSE[] SEC("license") = "Dual BSD/GPL";
//BPF map
/*struct {
__uint(type, BPF_MAP_TYPE_HASH);
__uint(max_entries, 8192);
__type(key, pid_t);
__type(value, char[5]);
} exec_start SEC(".maps");*/
//Ring buffer
/*struct {
__uint(type, BPF_MAP_TYPE_RINGBUF);
__uint(max_entries, 256 * 1024);
} rb SEC(".maps");*/
//Ethernet frame struct
struct eth_hdr {
unsigned char h_dest[ETH_ALEN];

View File

@@ -58,8 +58,7 @@ int print_entry(const char *filepath, const struct stat *info, const int typefla
printf(" %s (dangling symlink)\n", filepath);*/
else
if (typeflag == FTW_F)
1+1;
//printf(" %s\n", filepath);
printf(" %s\n", filepath);
/*else
if (typeflag == FTW_D || typeflag == FTW_DP)
printf(" %s/\n", filepath);

View File

@@ -9,8 +9,10 @@
#include <unistd.h>
#include "xdp_filter.skel.h"
#include "include/xdp_filter.h"
#include "../constants/constants.h"
#include "../common/constants.h"
#include "../common/map_defs.h"
#include "include/utils/files/path.h"
#include "include/utils/strings/regex.h"
#include "include/utils/structures/fdlist.h"
@@ -63,39 +65,56 @@ static void sig_handler(int sig){
exiting = true;
}
/*static int handle_event(void *ctx, void *data, size_t data_sz){
const struct event *e = data;
/**
* @brief Manages an event received via the ring buffer
* It's a message from th ebpf program
*
* @param ctx
* @param data
* @param data_sz
* @return int
*/
static int handle_rb_event(void *ctx, void *data, size_t data_size){
const struct rb_event *e = data;
//For time displaying
struct tm *tm;
char ts[32];
time_t t;
time(&t);
tm = localtime(&t);
strftime(ts, sizeof(ts), "%H:%M:%S", tm);
printf("NEW: %s\n",
e->payload);
if(e->event_type == INFO){
printf("%s INFO pid:%d code:%i, msg:%s\n", ts, e->pid, e->code, e->message);
}else if(e->event_type == DEBUG){
}else if(e->event_type == ERROR){
}else if(e->event_type == EXIT){
}else{
printf("UNRECOGNIZED RB EVENT RECEIVED");
return -1;
}
return 0;
}*/
}
int main(int argc, char**argv){
//struct ring_buffer *rb = NULL;
struct ring_buffer *rb = NULL;
struct xdp_filter_bpf *skel;
int err;
for (int arg = 1; arg < argc; arg++) {
//Ready to be used
/*for (int arg = 1; arg < argc; arg++) {
if (load_fd_kmsg(argv[arg])) {
fprintf(stderr, "%s.\n", strerror(errno));
return EXIT_FAILURE;
}
}
//int res = regex_match_fd("/proc/12/fd/1");
//printf("Returned %i\n", res);
}*/
unsigned int ifindex;
@@ -159,23 +178,40 @@ int main(int argc, char**argv){
goto cleanup;
}
// Attach tracepoints
/*err = xdp_filter_bpf__attach(skel);
// Attach tracepoint for
err = xdp_filter_bpf__attach(skel);
if (err) {
fprintf(stderr, "Failed to attach BPF skeleton\n");
goto cleanup;
}*/
}
//Attack BPF program to network interface
int flags = XDP_FLAGS_SKB_MODE;
int fd = bpf_program__fd(skel->progs.xdp_receive);
err = bpf_set_link_xdp_fd(ifindex, fd, flags);
/* Set up ring buffer polling */
rb = ring_buffer__new(bpf_map__fd(skel->maps.rb_comm), handle_rb_event, NULL, NULL);
if (!rb) {
err = -1;
fprintf(stderr, "Failed to create ring buffer\n");
goto cleanup;
}
//Now wait for messages from ebpf program
printf("Filter set and ready\n");
while (!exiting) {
/* trigger our BPF program */
fprintf(stderr, ".");
sleep(1);
err = ring_buffer__poll(rb, 100 /* timeout, ms */);
//Checking if a signal occured
if (err == -EINTR) {
err = 0;
break;
}
if (err < 0) {
printf("Error polling ring buffer: %d\n", err);
break;
}
}
//Received signal to stop, detach program from network interface
@@ -184,6 +220,7 @@ int main(int argc, char**argv){
cleanup:
ring_buffer__free(rb);
xdp_filter_bpf__destroy(skel);
return err < 0 ? -err : 0;