Skip to content

Commit

Permalink
Fix behavior around jumps with immediate values > 0x7fffffff in the i…
Browse files Browse the repository at this point in the history
…nterpreter (#447)

* Add test for sign extension in unsigned jump

Signed-off-by: Alan Jowett <alan.jowett@microsoft.com>

* Fix interpreter to match jit behavior

Signed-off-by: Alan Jowett <alan.jowett@microsoft.com>

* Make sign extension explicit

Signed-off-by: Alan Jowett <alan.jowett@microsoft.com>

* PR feedback

Signed-off-by: Alan Jowett <alan.jowett@microsoft.com>

---------

Signed-off-by: Alan Jowett <alan.jowett@microsoft.com>
Co-authored-by: Alan Jowett <alan.jowett@microsoft.com>
  • Loading branch information
Alan-Jowett and Alan Jowett committed May 8, 2024
1 parent db3e2d3 commit e8de891
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 12 deletions.
33 changes: 22 additions & 11 deletions vm/ubpf_vm.c
Expand Up @@ -293,6 +293,17 @@ i32(uint64_t x)
return x;
}

/**
* @brief Sign extend immediate value to a signed 64-bit value.
*
* @param[in] immediate The signed 32-bit immediate value to sign extend.
* @return The sign extended 64-bit value.
*/
static int64_t i64(int32_t immediate) {
return (int64_t)immediate;

}

#define IS_ALIGNED(x, a) (((uintptr_t)(x) & ((a)-1)) == 0)

inline static uint64_t
Expand Down Expand Up @@ -685,7 +696,7 @@ ubpf_exec(const struct ubpf_vm* vm, void* mem, size_t mem_len, uint64_t* bpf_ret
pc += inst.offset;
break;
case EBPF_OP_JEQ_IMM:
if (reg[inst.dst] == inst.imm) {
if (reg[inst.dst] == (uint64_t)i64(inst.imm)) {
pc += inst.offset;
}
break;
Expand All @@ -705,7 +716,7 @@ ubpf_exec(const struct ubpf_vm* vm, void* mem, size_t mem_len, uint64_t* bpf_ret
}
break;
case EBPF_OP_JGT_IMM:
if (reg[inst.dst] > u32(inst.imm)) {
if (reg[inst.dst] > (uint64_t)i64(inst.imm)) {
pc += inst.offset;
}
break;
Expand All @@ -725,7 +736,7 @@ ubpf_exec(const struct ubpf_vm* vm, void* mem, size_t mem_len, uint64_t* bpf_ret
}
break;
case EBPF_OP_JGE_IMM:
if (reg[inst.dst] >= u32(inst.imm)) {
if (reg[inst.dst] >= (uint64_t)i64(inst.imm)) {
pc += inst.offset;
}
break;
Expand All @@ -745,7 +756,7 @@ ubpf_exec(const struct ubpf_vm* vm, void* mem, size_t mem_len, uint64_t* bpf_ret
}
break;
case EBPF_OP_JLT_IMM:
if (reg[inst.dst] < u32(inst.imm)) {
if (reg[inst.dst] < (uint64_t)i64(inst.imm)) {
pc += inst.offset;
}
break;
Expand All @@ -765,7 +776,7 @@ ubpf_exec(const struct ubpf_vm* vm, void* mem, size_t mem_len, uint64_t* bpf_ret
}
break;
case EBPF_OP_JLE_IMM:
if (reg[inst.dst] <= u32(inst.imm)) {
if (reg[inst.dst] <= (uint64_t)i64(inst.imm)) {
pc += inst.offset;
}
break;
Expand All @@ -785,7 +796,7 @@ ubpf_exec(const struct ubpf_vm* vm, void* mem, size_t mem_len, uint64_t* bpf_ret
}
break;
case EBPF_OP_JSET_IMM:
if (reg[inst.dst] & inst.imm) {
if (reg[inst.dst] & (uint64_t)i64(inst.imm)) {
pc += inst.offset;
}
break;
Expand All @@ -805,7 +816,7 @@ ubpf_exec(const struct ubpf_vm* vm, void* mem, size_t mem_len, uint64_t* bpf_ret
}
break;
case EBPF_OP_JNE_IMM:
if (reg[inst.dst] != inst.imm) {
if (reg[inst.dst] != (uint64_t)i64(inst.imm)) {
pc += inst.offset;
}
break;
Expand All @@ -825,7 +836,7 @@ ubpf_exec(const struct ubpf_vm* vm, void* mem, size_t mem_len, uint64_t* bpf_ret
}
break;
case EBPF_OP_JSGT_IMM:
if ((int64_t)reg[inst.dst] > inst.imm) {
if ((int64_t)reg[inst.dst] > i64(inst.imm)) {
pc += inst.offset;
}
break;
Expand All @@ -845,7 +856,7 @@ ubpf_exec(const struct ubpf_vm* vm, void* mem, size_t mem_len, uint64_t* bpf_ret
}
break;
case EBPF_OP_JSGE_IMM:
if ((int64_t)reg[inst.dst] >= inst.imm) {
if ((int64_t)reg[inst.dst] >= i64(inst.imm)) {
pc += inst.offset;
}
break;
Expand All @@ -865,7 +876,7 @@ ubpf_exec(const struct ubpf_vm* vm, void* mem, size_t mem_len, uint64_t* bpf_ret
}
break;
case EBPF_OP_JSLT_IMM:
if ((int64_t)reg[inst.dst] < inst.imm) {
if ((int64_t)reg[inst.dst] < i64(inst.imm)) {
pc += inst.offset;
}
break;
Expand All @@ -885,7 +896,7 @@ ubpf_exec(const struct ubpf_vm* vm, void* mem, size_t mem_len, uint64_t* bpf_ret
}
break;
case EBPF_OP_JSLE_IMM:
if ((int64_t)reg[inst.dst] <= inst.imm) {
if ((int64_t)reg[inst.dst] <= i64(inst.imm)) {
pc += inst.offset;
}
break;
Expand Down

0 comments on commit e8de891

Please sign in to comment.