Both bpf_strncmp and user defined strncmp not work
- Dominant language
- C
- Stars
- 22.7k
- Forks
- 4.1k
- Avg merge
- 10d 4h
- Merged PRs (30d)
- 3
Description
# The bug
I want to do some string compare in bpfcc uprobe functions.
But both the built-in bpf_strncmp function and my strncmp can not work.
bpf_strncmp will always meet Permission denied.
my_strncmp seems to have encountered some compiler problems,
which can be bypassed by using -O0, but "-O0" may also fail under complicated circumstances.
another kind of workaround is to force the array to be on the stack by modifying the contents of the array.
ubuntu 24.04 with kernel 6.8.0-54-generic
# deb version of bcc
python3-bpfcc = 0.29.1+ds-1ubuntu7
llvm-18-runtime = 1:18.1.3-1
# git version of bcc
bcc = 0.33.0+c8515f71-py3.12
compiled with llvm-toolchain-19 = 1:19.1.1-1ubuntu1~24.04.2
# The code
```
# buggy.py
import sys, os, os.path
try:
from bpfcc import BPF
except:
from bcc import BPF
# bpf 程序
bpf_program = """
#include
#define NAMEBUF_SIZE 32
#define COMM_SIZE 20
static __always_inline int k_strncmp(const char *cs, int size, const char *ct)
{
int len = 0;
unsigned char c1, c2;
for (len=0; len>= 32 ; R3_w=scalar(smin=0,smax=umax=0xffffffff,var_off=(0x0; 0xffffffff))
20: (55) if r3 != 0x647770 goto pc+26 ; R3_w=0x647770
; char *retval = (char *)PT_REGS_RC(ctx);
21: (79) r3 = *(u64 *)(r6 +80) ; R3=scalar() R6=ctx()
; if (retval != NULL) {
22: (15) if r3 == 0x0 goto pc+24 ; R3=scalar(umin=1)
23: (bf) r1 = r10 ; R1_w=fp0 R10=fp0
24: (07) r1 += -64 ; R1_w=fp-64
; bpf_probe_read_str(&ret_name_buf, sizeof(ret_name_buf), retval);
25: (b7) r2 = 32 ; R2_w=32
26: (85) call bpf_probe_read_str#45 ; R0_w=scalar(smin=smin32=-4095,smax=smax32=32) fp-40=mmmmmmmm fp-48=mmmmmmmm fp-56=mmmmmmmm fp-64=mmmmmmmm
27: (b7) r1 = 0 ; R1_w=0
; c1 = *cs++;
28: (18) r3 = 0x0 ; R3_w=0
30: (0f) r3 += r1 ; R1_w=0 R3_w=0
31: (bf) r2 = r10 ; R2_w=fp0 R10=fp0
32: (07) r2 += -64 ; R2_w=fp-64
33: (0f) r2 += r1 ; R1_w=0 R2_w=fp-64
34: (71) r2 = *(u8 *)(r2 +0) ; R2_w=scalar(smin=smin32=0,smax=umax=smax32=umax32=255,var_off=(0x0; 0xff)) fp-64=mmmmmmmm
; c2 = *ct++;
35: (71) r3 = *(u8 *)(r3 +0)
R3 invalid mem access 'scalar'
processed 35 insns (limit 1000000) max_states_per_insn 0 total_states 1 peak_states 1 mark_read 1
Failed to load BPF program b'hook_getcwd_ret1': Permission denied
bpf: Failed to load program: Permission denied
0: R1=ctx() R10=fp0
; int hook_getcwd_ret2(struct pt_regs *ctx) {
0: (bf) r6 = r10 ; R6_w=fp0 R10=fp0
1: (07) r6 += -32 ; R6_w=fp-32
; bpf_get_current_comm(&comm, sizeof(comm));
2: (bf) r1 = r6 ; R1_w=fp-32 R6_w=fp-32
3: (b7) r2 = 20 ; R2_w=20
4: (85) call bpf_get_current_comm#16 ; R0_w=scalar() fp-16=????mmmm fp-24=mmmmmmmm fp-32=mmmmmmmm
5: (b7) r1 = 6584176 ; R1_w=0x647770
; const char comm_pattern[] = "pwd";
6: (63) *(u32 *)(r10 -36) = r1 ; R1_w=0x647770 R10=fp0 fp-40=mmmm????
7: (bf) r3 = r10 ; R3_w=fp0 R10=fp0
8: (07) r3 += -36 ; R3_w=fp-36
; if (bpf_strncmp(comm, COMM_SIZE, comm_pattern) == 0 ) {
9: (bf) r1 = r6 ; R1_w=fp-32 R6_w=fp-32
10: (b7) r2 = 20 ; R2_w=20
11: (85) call bpf_strncmp#182
R3 type=fp expected=map_value
processed 12 insns (limit 1000000) max_states_per_insn 0 total_states 0 peak_states 0 mark_read 0
Failed to load BPF program b'hook_getcwd_ret2': Permission denied
```
# My opinion
I have no idea with hook_getcwd_ret2 / bpf_strncmp, maybe my usage is wrong.
But hook_getcwd_ret1 looks very much like a compiler problem, which is obviously a null pointer dereference.
···
27: (b7) r1 = 0 ; R1_w=0
28: (18) r3 = 0x0 ; R3_w=0
30: (0f) r3 += r1 ; R1_w=0 R3_w=0
35: (71) r3 = *(u8 *)(r3 +0)
···
Contributor guide
No contributing guide indexed for this repository
Research direction
Start with buggy.py and the hook_getcwd_ret1 and hook_getcwd_ret2 entry points, then compare the verifier logs for the custom k_strncmp and bpf_strncmp cases. Reproduce with the stated Ubuntu, kernel, BCC, and LLVM versions; done means both programs load successfully and the comparison behavior is confirmed without relying on the reported workarounds.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- c, linux, python
- Domain
- compilers, devtools, operating-systems
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Needs clarification
- Newbie friendliness
- 32/100