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

Incorrect CALL code generation (emit_local_call) in JIT compiler #437

Closed
pcy190 opened this issue Apr 25, 2024 · 1 comment · Fixed by #497
Closed

Incorrect CALL code generation (emit_local_call) in JIT compiler #437

pcy190 opened this issue Apr 25, 2024 · 1 comment · Fixed by #497
Assignees

Comments

@pcy190
Copy link

pcy190 commented Apr 25, 2024

The JIT compiler does not emit check instructions for the target PC during code generation. Hence, any invalid jump target can be triggered without validation:

ubpf/vm/ubpf_jit_x86_64.c

Lines 102 to 118 in 7d6da19

emit_local_call(struct jit_state* state, uint32_t target_pc)
{
/*
* Pushing 4 * 8 = 32 bytes will maintain the invariant
* that the stack is 16-byte aligned.
*/
emit_push(state, map_register(BPF_REG_6));
emit_push(state, map_register(BPF_REG_7));
emit_push(state, map_register(BPF_REG_8));
emit_push(state, map_register(BPF_REG_9));
#if defined(_WIN32)
/* Windows x64 ABI requires home register space */
/* Allocate home register space - 4 registers */
emit_alu64_imm32(state, 0x81, 5, RSP, 4 * sizeof(uint64_t));
#endif
emit1(state, 0xe8); // e8 is the opcode for a CALL
emit_jump_target_address(state, target_pc);

Execute the following PoC program can result in the invalid behavior:

mov %r0, 0
call 0x0
exit

We get the unexpected error:

==222454==ERROR: UndefinedBehaviorSanitizer: SEGV on unknown address 0x55a4c2167e84 (pc 0x55a4c2167e84 bp 0x7fffc1588ab0 sp 0x7fffc15888a8 T222454)
==222454==The signal is caused by a READ memory access.
==222454==Hint: PC is at a non-executable region. Maybe a wild jump?
    #0 0x55a4c2167e84  ([heap]+0x1ae84)

and

==224895==ERROR: UndefinedBehaviorSanitizer: SEGV on unknown address 0x000000000000 (pc 0x000000000000 bp 0x7ffd7a20f5d0 sp 0x7ffd7a20f3c8 T224895)
==224895==Hint: pc points to the zero page.
==224895==The signal is caused by a READ memory access.
==224895==Hint: address points to the zero page.
@hawkinsw
Copy link
Collaborator

Thank you for the report, @pcy190 . I believe that this is something we would expect that a verifier would reject. In fact, @Alan-Jowett has proposed that this type of call be added a list of behavior that is not allowed under the to-be-written psABI for uBPF.

That said, the specification does not appear to prohibit code that works like this. What's more, as far as I can tell, the code that you write should work (although it would not actually do anything).

I believe that @Alan-Jowett 's recent change to the uBPF runtime to support overlapped functions might have remedied this situation. I will double check. If it did not, then I will propose a fix.

Thank you (again) for the report!

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

Successfully merging a pull request may close this issue.

2 participants