Skip to content

Commit

Permalink
Introduce toggle to enable/disable bounds_check.
Browse files Browse the repository at this point in the history
bounds_check routine assumes that memory to read / write may only be on the stack or within ubpf code itself.
The toggle allows disabling the check when the assumption is not correct.
  • Loading branch information
Oleg Pigal authored and pchaigno committed Apr 29, 2020
1 parent 4cbf799 commit 089f627
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 4 deletions.
9 changes: 9 additions & 0 deletions vm/inc/ubpf.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,15 @@ typedef uint64_t (*ubpf_jit_fn)(void *mem, size_t mem_len);
struct ubpf_vm *ubpf_create(void);
void ubpf_destroy(struct ubpf_vm *vm);

/*
* Enable / disable bounds_check
*
* Bounds check is enabled by default, but it may be too restrictive
* Pass true to enable, false to disable
* Returns previous state
*/
bool toggle_bounds_check(struct ubpf_vm *vm, bool enable);

/*
* Register an external function
*
Expand Down
1 change: 1 addition & 0 deletions vm/ubpf_int.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ struct ubpf_vm {
size_t jitted_size;
ext_func *ext_funcs;
const char **ext_func_names;
bool bounds_check_enabled;
};

char *ubpf_error(const char *fmt, ...);
Expand Down
18 changes: 14 additions & 4 deletions vm/ubpf_vm.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,14 @@
#define MAX_EXT_FUNCS 64

static bool validate(const struct ubpf_vm *vm, const struct ebpf_inst *insts, uint32_t num_insts, char **errmsg);
static bool bounds_check(void *addr, int size, const char *type, uint16_t cur_pc, void *mem, size_t mem_len, void *stack);
static bool bounds_check(const struct ubpf_vm *vm, void *addr, int size, const char *type, uint16_t cur_pc, void *mem, size_t mem_len, void *stack);

bool toggle_bounds_check(struct ubpf_vm *vm, bool enable)
{
bool old = vm->bounds_check_enabled;
vm->bounds_check_enabled = enable;
return old;
}

struct ubpf_vm *
ubpf_create(void)
Expand All @@ -49,6 +56,7 @@ ubpf_create(void)
return NULL;
}

vm->bounds_check_enabled = true;
return vm;
}

Expand Down Expand Up @@ -366,13 +374,13 @@ ubpf_exec(const struct ubpf_vm *vm, void *mem, size_t mem_len)
*/
#define BOUNDS_CHECK_LOAD(size) \
do { \
if (!bounds_check((void *)reg[inst.src] + inst.offset, size, "load", cur_pc, mem, mem_len, stack)) { \
if (!bounds_check(vm, (void *)reg[inst.src] + inst.offset, size, "load", cur_pc, mem, mem_len, stack)) { \
return UINT64_MAX; \
} \
} while (0)
#define BOUNDS_CHECK_STORE(size) \
do { \
if (!bounds_check((void *)reg[inst.dst] + inst.offset, size, "store", cur_pc, mem, mem_len, stack)) { \
if (!bounds_check(vm, (void *)reg[inst.dst] + inst.offset, size, "store", cur_pc, mem, mem_len, stack)) { \
return UINT64_MAX; \
} \
} while (0)
Expand Down Expand Up @@ -732,8 +740,10 @@ validate(const struct ubpf_vm *vm, const struct ebpf_inst *insts, uint32_t num_i
}

static bool
bounds_check(void *addr, int size, const char *type, uint16_t cur_pc, void *mem, size_t mem_len, void *stack)
bounds_check(const struct ubpf_vm *vm, void *addr, int size, const char *type, uint16_t cur_pc, void *mem, size_t mem_len, void *stack)
{
if (!vm->bounds_check_enabled)
return true;
if (mem && (addr >= mem && (addr + size) <= (mem + mem_len))) {
/* Context access */
return true;
Expand Down

0 comments on commit 089f627

Please sign in to comment.