Verifier error when logging an integer casted from a pt_regs register
willfindlay opened this issue · 0 comments
willfindlay commented
The following minimal example causes a verifier error on Linux 5.14. Note that inserting into the map works just fine, but commenting out the map insertion and using aya_log::info!()
instead results in the verifier error. N.B. I first noticed this when I was testing my new getter implementation (see aya-rs/aya#71) but using the ordinary method (as done below) still produces the same error. For context, I'm attaching the kprobe to try_to_wake_up()
.
#![no_std]
#![no_main]
use aya_bpf::{
cty::c_int,
helpers::bpf_probe_read,
macros::{kprobe, map},
maps::HashMap,
programs::ProbeContext,
};
use aya_log_ebpf::info;
#[map]
static mut MAP: HashMap<c_int, c_int> = HashMap::with_max_entries(1024, 0);
#[kprobe(name = "kprobe_args_test")]
pub fn kprobe_args_test(ctx: ProbeContext) -> u32 {
match unsafe { try_kprobe_args_test(ctx) } {
Ok(ret) => ret,
Err(ret) => ret,
}
}
unsafe fn try_kprobe_args_test(ctx: ProbeContext) -> Result<u32, u32> {
// Get the second argument from struct pt_regs
let state: c_int = match (*ctx.regs).rsi() {
Some(state) => state as c_int,
None => return Err(1),
};
// This works no problem:
let _ = MAP.insert(&state, &state, 0);
// This causes the verifier to complain as follows:
// invalid read from stack off -20+0 size 1
// info!(&ctx, "hello kprobe world, with argument {}", state);
Ok(0)
}
#[panic_handler]
fn panic(_info: &core::panic::PanicInfo) -> ! {
unsafe { core::hint::unreachable_unchecked() }
}
Here is the message from the verifier:
/* Lots of other output above */
394: (85) call pc+11
caller:
frame1: R6=invP20 R7=fp-40 R8=invP50 R10=fp0 fp-8=mmmmmmmm fp-16=mmmmmmmm fp-24=mmm?????
callee:
frame2: R1_w=map_value(id=0,off=185,ks=4,vs=1024,imm=0) R2_w=fp-20 R3_w=invP20 R4=invP0 R5=invP10 R10=fp0
406: frame2: R1_w=map_value(id=0,off=185,ks=4,vs=1024,imm=0) R2_w=fp-20 R3_w=invP20 R4=invP0 R5=invP10 R10=fp0
406: (bf) r0 = r1
407: frame2: R0=map_value(id=0,off=185,ks=4,vs=1024,imm=0) R1=map_value(id=0,off=185,ks=4,vs=1024,imm=0) R2=fp-20 R3=invP20 R4=invP0 R5=invP10 R10=fp0
407: (15) if r3 == 0x0 goto pc+9
408: frame2: R0=map_value(id=0,off=185,ks=4,vs=1024,imm=0) R1=map_value(id=0,off=185,ks=4,vs=1024,imm=0) R2=fp-20 R3=invP20 R4=invP0 R5=invP10 R10=fp0
408: (b7) r1 = 0
409: frame2: R0=map_value(id=0,off=185,ks=4,vs=1024,imm=0) R1_w=invP0 R2=fp-20 R3=invP20 R4=invP0 R5=invP10 R10=fp0
409: (bf) r4 = r0
410: frame2: R0=map_value(id=0,off=185,ks=4,vs=1024,imm=0) R1_w=invP0 R2=fp-20 R3=invP20 R4_w=map_value(id=0,off=185,ks=4,vs=1024,imm=0) R5=invP10 R10=fp0
410: (0f) r4 += r1
411: frame2: R0=map_value(id=0,off=185,ks=4,vs=1024,imm=0) R1_w=invP0 R2=fp-20 R3=invP20 R4_w=map_value(id=0,off=185,ks=4,vs=1024,imm=0) R5=invP10 R10=fp0
411: (bf) r5 = r2
412: frame2: R0=map_value(id=0,off=185,ks=4,vs=1024,imm=0) R1_w=invP0 R2=fp-20 R3=invP20 R4_w=map_value(id=0,off=185,ks=4,vs=1024,imm=0) R5_w=fp-20 R10=fp0
412: (0f) r5 += r1
413: frame2: R0=map_value(id=0,off=185,ks=4,vs=1024,imm=0) R1_w=invP0 R2=fp-20 R3=invP20 R4_w=map_value(id=0,off=185,ks=4,vs=1024,imm=0) R5_w=fp-20 R10=fp0
413: (71) r5 = *(u8 *)(r5 +0)
invalid read from stack off -20+0 size 1
verification time 4496 usec
stack depth 40+20+0
processed 623 insns (limit 1000000) max_states_per_insn 3 total_states 11 peak_states 11 mark_read 8
: Permission denied (os error 13)