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

Memory out-of-bound access in the ubpf_fetch_instruction when executing unterminated eBPF program #433

Closed
pcy190 opened this issue Apr 25, 2024 · 1 comment

Comments

@pcy190
Copy link

pcy190 commented Apr 25, 2024

The current implementation of the interpreter does not check the termination of the eBPF program. While executing an unterminated eBPF program, the interpreter would make an invalid pc that exceeds the program instruction length.

ubpf/vm/ubpf_vm.c

Lines 388 to 390 in 7d6da19

while (1) {
const uint16_t cur_pc = pc;
struct ebpf_inst inst = ubpf_fetch_instruction(vm, pc++);

The following PoC program demonstrates the out-of-bound memory access when uBPF executes it.
The bytecode of the program is 2f4242424242452a, and the disassembled code is mul %r2, %r4.

Running it would trigger an invalid memory read:

==48160==ERROR: UndefinedBehaviorSanitizer: SEGV on unknown address 0x5567e2f23000 (pc 0x5567e071111c bp 0x000000005567 sp 0x7ffca7fb67f0 T48160)
==48160==The signal is caused by a READ memory access.
    #0 0x5567e071111c in ubpf_fetch_instruction /ubpf/vm/ubpf_vm.c
    #1 0x5567e071111c in ubpf_exec /ubpf/vm/ubpf_vm.c:390:33

Patch suggestion:
In the while loop, we should check whether the PC is equal to or larger than the vm->num_insts:

    while (1) {
        const uint16_t cur_pc = pc;

        if (pc >= vm->num_insts){
            return_value = -1; 
            goto cleanup;
        }

        struct ebpf_inst inst = ubpf_fetch_instruction(vm, pc++);
@Alan-Jowett
Copy link
Collaborator

Thanks @pcy190. This should now be fixed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants