Skip to content
Open
Show file tree
Hide file tree
Changes from all 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: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,7 @@ sock_example
sockex1
get-rekt-hardened
loader
*.out
*.gch
*~
.*~
.*~
5 changes: 4 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ BPFCC=clang
BPFLLC=llc

cprogs = sock_example get-rekt-hardened
bpfprogs = sockex1
bpfprogs = sockex1 elf_parse

all: $(cprogs) $(bpfprogs)
bash perm.sh
Expand All @@ -17,6 +17,9 @@ sock_example: sock_example.o libbpf.o
sockex1: sockex1_user.o sockex1_kern.o bpf_load.o libbpf.o
$(CC) sockex1_user.o bpf_load.o libbpf.o -lelf -o $@

elf_parse: elf_parse.o bpf_load.o libbpf.o
$(CC) elf_parse.o bpf_load.o libbpf.o -lelf -o $@

sockex1_kern.o: sockex1_kern.c
$(BPFCC) -O2 -emit-llvm -c $< -o -| $(BPFLLC) -march=bpf -filetype=obj -o $@
$(BPFCC) -O2 -emit-llvm -c $< -o -| $(BPFLLC) -march=bpf -filetype=asm -o $@.s
Expand Down
112 changes: 110 additions & 2 deletions bpf_load.c
Original file line number Diff line number Diff line change
Expand Up @@ -323,6 +323,115 @@ int load_bpf_file(char *path)
close(fd);
return 0;
}
int get_prog_and_data(char *path, char *progname,
int progname_len, int *prog_len,
struct bpf_insn** prog, int *map_len,
struct bpf_map_def** maps, Elf_Data** symtab, uint64_t *num_entries)
{
int fd, i;
Elf *elf;
GElf_Ehdr ehdr;
GElf_Shdr shdr, shdr_prog;
Elf_Data *data, *data_prog, *symbols = NULL;
char *shname, *shname_prog;

if (elf_version(EV_CURRENT) == EV_NONE)
return 1;

fd = open(path, O_RDONLY, 0);
if (fd < 0)
return 1;

elf = elf_begin(fd, ELF_C_READ, NULL);

if (!elf)
return 1;

if (gelf_getehdr(elf, &ehdr) != &ehdr)
return 1;

/* scan over all elf sections to get license and map info */
for (i = 1; i < ehdr.e_shnum; i++) {

if (get_sec(elf, i, &ehdr, &shname, &shdr, &data))
continue;

if (0) /* helpful for llvm debugging */
printf("section %d:%s data %p size %zd link %d flags %d\n",
i, shname, data->d_buf, data->d_size,
shdr.sh_link, (int) shdr.sh_flags);

if (strcmp(shname, "license") == 0) {
processed_sec[i] = true;
memcpy(license, data->d_buf, data->d_size);
} else if (strcmp(shname, "version") == 0) {
processed_sec[i] = true;
if (data->d_size != sizeof(int)) {
printf("invalid size of version section %zd\n",
data->d_size);
return 1;
}
memcpy(&kern_version, data->d_buf, sizeof(int));
} else if (strcmp(shname, "maps") == 0) {
processed_sec[i] = true;
if (load_maps(data->d_buf, data->d_size))
return 1;
else {
*map_len = data->d_size;
*maps = data->d_buf;
}
} else if (shdr.sh_type == SHT_SYMTAB) {
*symtab = data;
*num_entries = (uint64_t)(shdr.sh_size / shdr.sh_entsize);
symbols = data;
}
}

/* load programs that need map fixup (relocations) */
for (i = 1; i < ehdr.e_shnum; i++) {
if (get_sec(elf, i, &ehdr, &shname, &shdr, &data))
continue;
if (shdr.sh_type == SHT_REL) {
struct bpf_insn *insns;

if (get_sec(elf, shdr.sh_info, &ehdr, &shname_prog,
&shdr_prog, &data_prog))
continue;

insns = (struct bpf_insn *) data_prog->d_buf;

processed_sec[shdr.sh_info] = true;
processed_sec[i] = true;

if (parse_relo_and_apply(data, symbols, &shdr, insns))
continue;
if (memcmp(shname_prog, progname, progname_len) == 0) {
*prog_len = data_prog->d_size;
*prog = insns;
return 0;
}
}
}

/* load programs that don't use maps */
for (i = 1; i < ehdr.e_shnum; i++) {

if (processed_sec[i])
continue;

if (get_sec(elf, i, &ehdr, &shname, &shdr, &data))
continue;

if (memcmp(shname, progname, progname_len) == 0) {

*prog_len = data->d_size;
*prog = data->d_buf;
return 0;
}
}
close(fd);
return 0;
}

int get_prog(char *path, char *progname,
int progname_len, int *prog_len,
Expand Down Expand Up @@ -383,7 +492,6 @@ int get_prog(char *path, char *progname,

/* load programs that need map fixup (relocations) */
for (i = 1; i < ehdr.e_shnum; i++) {

if (get_sec(elf, i, &ehdr, &shname, &shdr, &data))
continue;
if (shdr.sh_type == SHT_REL) {
Expand All @@ -400,7 +508,6 @@ int get_prog(char *path, char *progname,

if (parse_relo_and_apply(data, symbols, &shdr, insns))
continue;

if (memcmp(shname_prog, progname, progname_len) == 0) {
*prog_len = data_prog->d_size;
*prog = insns;
Expand All @@ -419,6 +526,7 @@ int get_prog(char *path, char *progname,
continue;

if (memcmp(shname, progname, progname_len) == 0) {

*prog_len = data->d_size;
*prog = data->d_buf;
return 0;
Expand Down
8 changes: 7 additions & 1 deletion bpf_load.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
#define MAX_MAPS 32
#define MAX_PROGS 32

#include <gelf.h>
#include "bpf_helpers.h"
extern int map_fd[MAX_MAPS];
extern int prog_fd[MAX_PROGS];
extern int event_fd[MAX_PROGS];
Expand All @@ -26,7 +28,11 @@ int load_bpf_file(char *path);
* is requested. */
int get_prog(char *path, char *progname, int progname_len, int
*prog_len, struct bpf_insn **prog);

int get_prog_and_data(char *path, char *progname,
int progname_len, int *prog_len,
struct bpf_insn** prog, int *map_len,
struct bpf_map_def** maps, Elf_Data ** symtab, uint64_t *num_entries);

void read_trace_pipe(void);

#endif
Loading