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

tools/ttysnoop: Fix uninitialized 'buf' error #4453

Merged
merged 1 commit into from
Feb 3, 2023

Conversation

Rtoax
Copy link
Contributor

@Rtoax Rtoax commented Jan 29, 2023

ENV: LLVM 13.0.1, Kernel 5.15.67, aarch64

Overview of the error:

The verifier is unhappy, if '(r10 -32)' is not initialized, see also [0].

  $ sudo ./ttysnoop.py 10
  bpf: Failed to load program: Permission denied
  3: (7b) *(u64 *)(r10 -8) = r6
  4: (7b) *(u64 *)(r10 -16) = r6
  5: (7b) *(u64 *)(r10 -24) = r6
  6: (bf) r1 = r10
  ...
  91: (67) r0 <<= 32
  92: (77) r0 >>= 32
  ; if (bpf_probe_read_user(&data->buf, BUFSIZE, (void *)buf))
  93: (55) if r0 != 0x0 goto pc+356
  R0_w=inv0 R6=invP0 R7=map_value(id=0,off=0,ks=4,vs=260,imm=0) R8=map_value(
    id=0,off=4,ks=4,vs=260,imm=0) R9=inv256 R10=fp0 fp-8=mmmmmmmm
    fp-16=mmmmmmmm fp-24=mmmmmmmm
  94: (79) r2 = *(u64 *)(r10 -32)
  invalid read from stack R10 off=-32 size=8
  processed 593 insns (limit 1000000) max_states_per_insn 1 total_states 48
    peak_states 48 mark_read 3

This issue can also be resolved by upgrading LLVM>=14 and recompile and install bcc.

[0] #2623

Detail:

$ sudo ./ttysnoop.py 10
bpf: Failed to load program: Permission denied
; struct kiocb *iocb = (struct kiocb *)ctx->regs[0]; struct iov_iter *from = (struct iov_iter *)ctx->regs[1];
0: (79) r7 = *(u64 *)(r1 +8)
; struct kiocb *iocb = (struct kiocb *)ctx->regs[0]; struct iov_iter *from = (struct iov_iter *)ctx->regs[1];
1: (79) r3 = *(u64 *)(r1 +0)
2: (b7) r6 = 0
; if (({ typeof(unsigned long) _val; __builtin_memset(&_val, 0, sizeof(_val)); bpf_probe_read(&_val, sizeof(_val), (void *)&({ typeof(struct inode *) _val; __builtin_memset(&_val, 0, sizeof(_val)); bpf_probe_read(&_val, sizeof(_val), (void *)&({ typeof(struct file *) _val; __builtin_memset(&_val, 0, sizeof(_val)); bpf_probe_read(&_val, sizeof(_val), (void *)&iocb->ki_filp); _val; })->f_inode); _val; })->i_ino); _val; }) != 13)
3: (7b) *(u64 *)(r10 -8) = r6
last_idx 3 first_idx 0
regs=40 stack=0 before 2: (b7) r6 = 0
; if (({ typeof(unsigned long) _val; __builtin_memset(&_val, 0, sizeof(_val)); bpf_probe_read(&_val, sizeof(_val), (void *)&({ typeof(struct inode *) _val; __builtin_memset(&_val, 0, sizeof(_val)); bpf_probe_read(&_val, sizeof(_val), (void *)&({ typeof(struct file *) _val; __builtin_memset(&_val, 0, sizeof(_val)); bpf_probe_read(&_val, sizeof(_val), (void *)&iocb->ki_filp); _val; })->f_inode); _val; })->i_ino); _val; }) != 13)
4: (7b) *(u64 *)(r10 -16) = r6
; if (({ typeof(unsigned long) _val; __builtin_memset(&_val, 0, sizeof(_val)); bpf_probe_read(&_val, sizeof(_val), (void *)&({ typeof(struct inode *) _val; __builtin_memset(&_val, 0, sizeof(_val)); bpf_probe_read(&_val, sizeof(_val), (void *)&({ typeof(struct file *) _val; __builtin_memset(&_val, 0, sizeof(_val)); bpf_probe_read(&_val, sizeof(_val), (void *)&iocb->ki_filp); _val; })->f_inode); _val; })->i_ino); _val; }) != 13)
5: (7b) *(u64 *)(r10 -24) = r6
6: (bf) r1 = r10
;
7: (07) r1 += -24
; if (({ typeof(unsigned long) _val; __builtin_memset(&_val, 0, sizeof(_val)); bpf_probe_read(&_val, sizeof(_val), (void *)&({ typeof(struct inode *) _val; __builtin_memset(&_val, 0, sizeof(_val)); bpf_probe_read(&_val, sizeof(_val), (void *)&({ typeof(struct file *) _val; __builtin_memset(&_val, 0, sizeof(_val)); bpf_probe_read(&_val, sizeof(_val), (void *)&iocb->ki_filp); _val; })->f_inode); _val; })->i_ino); _val; }) != 13)
8: (b7) r2 = 8
9: (85) call bpf_probe_read#4
last_idx 9 first_idx 0
regs=4 stack=0 before 8: (b7) r2 = 8
; if (({ typeof(unsigned long) _val; __builtin_memset(&_val, 0, sizeof(_val)); bpf_probe_read(&_val, sizeof(_val), (void *)&({ typeof(struct inode *) _val; __builtin_memset(&_val, 0, sizeof(_val)); bpf_probe_read(&_val, sizeof(_val), (void *)&({ typeof(struct file *) _val; __builtin_memset(&_val, 0, sizeof(_val)); bpf_probe_read(&_val, sizeof(_val), (void *)&iocb->ki_filp); _val; })->f_inode); _val; })->i_ino); _val; }) != 13)
10: (79) r3 = *(u64 *)(r10 -24)
; if (({ typeof(unsigned long) _val; __builtin_memset(&_val, 0, sizeof(_val)); bpf_probe_read(&_val, sizeof(_val), (void *)&({ typeof(struct inode *) _val; __builtin_memset(&_val, 0, sizeof(_val)); bpf_probe_read(&_val, sizeof(_val), (void *)&({ typeof(struct file *) _val; __builtin_memset(&_val, 0, sizeof(_val)); bpf_probe_read(&_val, sizeof(_val), (void *)&iocb->ki_filp); _val; })->f_inode); _val; })->i_ino); _val; }) != 13)
11: (07) r3 += 32
12: (bf) r1 = r10
;
13: (07) r1 += -16
; if (({ typeof(unsigned long) _val; __builtin_memset(&_val, 0, sizeof(_val)); bpf_probe_read(&_val, sizeof(_val), (void *)&({ typeof(struct inode *) _val; __builtin_memset(&_val, 0, sizeof(_val)); bpf_probe_read(&_val, sizeof(_val), (void *)&({ typeof(struct file *) _val; __builtin_memset(&_val, 0, sizeof(_val)); bpf_probe_read(&_val, sizeof(_val), (void *)&iocb->ki_filp); _val; })->f_inode); _val; })->i_ino); _val; }) != 13)
14: (b7) r2 = 8
15: (85) call bpf_probe_read#4
last_idx 15 first_idx 0
regs=4 stack=0 before 14: (b7) r2 = 8
; if (({ typeof(unsigned long) _val; __builtin_memset(&_val, 0, sizeof(_val)); bpf_probe_read(&_val, sizeof(_val), (void *)&({ typeof(struct inode *) _val; __builtin_memset(&_val, 0, sizeof(_val)); bpf_probe_read(&_val, sizeof(_val), (void *)&({ typeof(struct file *) _val; __builtin_memset(&_val, 0, sizeof(_val)); bpf_probe_read(&_val, sizeof(_val), (void *)&iocb->ki_filp); _val; })->f_inode); _val; })->i_ino); _val; }) != 13)
16: (79) r3 = *(u64 *)(r10 -16)
; if (({ typeof(unsigned long) _val; __builtin_memset(&_val, 0, sizeof(_val)); bpf_probe_read(&_val, sizeof(_val), (void *)&({ typeof(struct inode *) _val; __builtin_memset(&_val, 0, sizeof(_val)); bpf_probe_read(&_val, sizeof(_val), (void *)&({ typeof(struct file *) _val; __builtin_memset(&_val, 0, sizeof(_val)); bpf_probe_read(&_val, sizeof(_val), (void *)&iocb->ki_filp); _val; })->f_inode); _val; })->i_ino); _val; }) != 13)
17: (07) r3 += 64
18: (bf) r1 = r10
;
19: (07) r1 += -8
; if (({ typeof(unsigned long) _val; __builtin_memset(&_val, 0, sizeof(_val)); bpf_probe_read(&_val, sizeof(_val), (void *)&({ typeof(struct inode *) _val; __builtin_memset(&_val, 0, sizeof(_val)); bpf_probe_read(&_val, sizeof(_val), (void *)&({ typeof(struct file *) _val; __builtin_memset(&_val, 0, sizeof(_val)); bpf_probe_read(&_val, sizeof(_val), (void *)&iocb->ki_filp); _val; })->f_inode); _val; })->i_ino); _val; }) != 13)
20: (b7) r2 = 8
21: (85) call bpf_probe_read#4
last_idx 21 first_idx 16
regs=4 stack=0 before 20: (b7) r2 = 8
; if (({ typeof(unsigned long) _val; __builtin_memset(&_val, 0, sizeof(_val)); bpf_probe_read(&_val, sizeof(_val), (void *)&({ typeof(struct inode *) _val; __builtin_memset(&_val, 0, sizeof(_val)); bpf_probe_read(&_val, sizeof(_val), (void *)&({ typeof(struct file *) _val; __builtin_memset(&_val, 0, sizeof(_val)); bpf_probe_read(&_val, sizeof(_val), (void *)&iocb->ki_filp); _val; })->f_inode); _val; })->i_ino); _val; }) != 13)
22: (79) r1 = *(u64 *)(r10 -8)
; if (({ typeof(unsigned long) _val; __builtin_memset(&_val, 0, sizeof(_val)); bpf_probe_read(&_val, sizeof(_val), (void *)&({ typeof(struct inode *) _val; __builtin_memset(&_val, 0, sizeof(_val)); bpf_probe_read(&_val, sizeof(_val), (void *)&({ typeof(struct file *) _val; __builtin_memset(&_val, 0, sizeof(_val)); bpf_probe_read(&_val, sizeof(_val), (void *)&iocb->ki_filp); _val; })->f_inode); _val; })->i_ino); _val; }) != 13)
23: (55) if r1 != 0xd goto pc+426
 R0_w=inv(id=0) R1_w=inv13 R6=invP0 R7=inv(id=0) R10=fp0 fp-8=mmmmmmmm fp-16=mmmmmmmm fp-24=mmmmmmmm
; if ( ({ typeof(u8) _val; __builtin_memset(&_val, 0, sizeof(_val)); bpf_probe_read(&_val, sizeof(_val), (void *)&from->iter_type); _val; }) != ITER_IOVEC)
24: (73) *(u8 *)(r10 -8) = r6
25: (bf) r1 = r10
;
26: (07) r1 += -8
; if ( ({ typeof(u8) _val; __builtin_memset(&_val, 0, sizeof(_val)); bpf_probe_read(&_val, sizeof(_val), (void *)&from->iter_type); _val; }) != ITER_IOVEC)
27: (b7) r2 = 1
28: (bf) r3 = r7
29: (85) call bpf_probe_read#4
last_idx 29 first_idx 16
regs=4 stack=0 before 28: (bf) r3 = r7
regs=4 stack=0 before 27: (b7) r2 = 1
; if ( ({ typeof(u8) _val; __builtin_memset(&_val, 0, sizeof(_val)); bpf_probe_read(&_val, sizeof(_val), (void *)&from->iter_type); _val; }) != ITER_IOVEC)
30: (71) r1 = *(u8 *)(r10 -8)
; if ( ({ typeof(u8) _val; __builtin_memset(&_val, 0, sizeof(_val)); bpf_probe_read(&_val, sizeof(_val), (void *)&from->iter_type); _val; }) != ITER_IOVEC)
31: (55) if r1 != 0x0 goto pc+418
 R0=inv(id=0) R1_w=inv0 R6=invP0 R7=inv(id=1) R10=fp0 fp-8=mmmmmmmm fp-16=mmmmmmmm fp-24=mmmmmmmm
32: (b7) r6 = 0
; if (({ typeof(bool) _val; __builtin_memset(&_val, 0, sizeof(_val)); bpf_probe_read(&_val, sizeof(_val), (void *)&from->data_source); _val; }) != WRITE)
33: (73) *(u8 *)(r10 -8) = r6
last_idx 33 first_idx 30
regs=40 stack=0 before 32: (b7) r6 = 0
; if (({ typeof(bool) _val; __builtin_memset(&_val, 0, sizeof(_val)); bpf_probe_read(&_val, sizeof(_val), (void *)&from->data_source); _val; }) != WRITE)
34: (bf) r3 = r7
35: (07) r3 += 2
36: (bf) r1 = r10
;
37: (07) r1 += -8
; if (({ typeof(bool) _val; __builtin_memset(&_val, 0, sizeof(_val)); bpf_probe_read(&_val, sizeof(_val), (void *)&from->data_source); _val; }) != WRITE)
38: (b7) r2 = 1
39: (85) call bpf_probe_read#4
last_idx 39 first_idx 30
regs=4 stack=0 before 38: (b7) r2 = 1
; if (({ typeof(bool) _val; __builtin_memset(&_val, 0, sizeof(_val)); bpf_probe_read(&_val, sizeof(_val), (void *)&from->data_source); _val; }) != WRITE)
40: (71) r1 = *(u8 *)(r10 -8)
; if (({ typeof(bool) _val; __builtin_memset(&_val, 0, sizeof(_val)); bpf_probe_read(&_val, sizeof(_val), (void *)&from->data_source); _val; }) != WRITE)
41: (55) if r1 != 0x1 goto pc+408
 R0=inv(id=0) R1_w=inv1 R6=invP0 R7=inv(id=1) R10=fp0 fp-8=mmmmmmmm fp-16=mmmmmmmm fp-24=mmmmmmmm
; switch (({ typeof(u8) _val; __builtin_memset(&_val, 0, sizeof(_val)); bpf_probe_read(&_val, sizeof(_val), (void *)&from->iter_type); _val; })) {
42: (73) *(u8 *)(r10 -8) = r6
43: (bf) r1 = r10
;
44: (07) r1 += -8
; switch (({ typeof(u8) _val; __builtin_memset(&_val, 0, sizeof(_val)); bpf_probe_read(&_val, sizeof(_val), (void *)&from->iter_type); _val; })) {
45: (b7) r2 = 1
46: (bf) r3 = r7
47: (85) call bpf_probe_read#4
last_idx 47 first_idx 40
regs=4 stack=0 before 46: (bf) r3 = r7
regs=4 stack=0 before 45: (b7) r2 = 1
; switch (({ typeof(u8) _val; __builtin_memset(&_val, 0, sizeof(_val)); bpf_probe_read(&_val, sizeof(_val), (void *)&from->iter_type); _val; })) {
48: (71) r1 = *(u8 *)(r10 -8)
; switch (({ typeof(u8) _val; __builtin_memset(&_val, 0, sizeof(_val)); bpf_probe_read(&_val, sizeof(_val), (void *)&from->iter_type); _val; })) {
49: (55) if r1 != 0x0 goto pc+25

from 49 to 75: R0=inv(id=0) R1=inv(id=0,umax_value=255,var_off=(0x0; 0xff)) R6=invP0 R7=inv(id=1) R10=fp0 fp-8=mmmmmmmm fp-16=mmmmmmmm fp-24=mmmmmmmm
; count = ({ typeof(const size_t) _val; __builtin_memset(&_val, 0, sizeof(_val)); bpf_probe_read(&_val, sizeof(_val), (void *)&kvec->iov_len); _val; });
75: (b7) r1 = 0
; int zero = 0, i;
76: (63) *(u32 *)(r10 -8) = r1
last_idx 76 first_idx 75
regs=2 stack=0 before 75: (b7) r1 = 0
; data = bpf_map_lookup_elem((void *)bpf_pseudo_fd(1, -1), &zero);
77: (18) r1 = 0xffff2024936a9c00
79: (bf) r2 = r10
;
80: (07) r2 += -8
; data = bpf_map_lookup_elem((void *)bpf_pseudo_fd(1, -1), &zero);
81: (85) call bpf_map_lookup_elem#1
82: (bf) r7 = r0
; if (!data)
83: (15) if r7 == 0x0 goto pc+366
 R0_w=map_value(id=0,off=0,ks=4,vs=260,imm=0) R6=invP0 R7_w=map_value(id=0,off=0,ks=4,vs=260,imm=0) R10=fp0 fp-8=mmmmmmmm fp-16=mmmmmmmm fp-24=mmmmmmmm
; if (bpf_probe_read_user(&data->buf, BUFSIZE, (void *)buf))
84: (bf) r8 = r7
85: (07) r8 += 4
86: (b7) r9 = 256
; if (bpf_probe_read_user(&data->buf, BUFSIZE, (void *)buf))
87: (bf) r1 = r8
88: (b7) r2 = 256
89: (bf) r3 = r6
90: (85) call bpf_probe_read_user#112
 R0_w=map_value(id=0,off=0,ks=4,vs=260,imm=0) R1_w=map_value(id=0,off=4,ks=4,vs=260,imm=0) R2_w=inv256 R3_w=invP0 R6=invP0 R7_w=map_value(id=0,off=0,ks=4,vs=260,imm=0) R8_w=map_value(id=0,off=4,ks=4,vs=260,imm=0) R9_w=inv256 R10=fp0 fp-8=mmmmmmmm fp-16=mmmmmmmm fp-24=mmmmmmmm
last_idx 90 first_idx 75
regs=4 stack=0 before 89: (bf) r3 = r6
regs=4 stack=0 before 88: (b7) r2 = 256
91: (67) r0 <<= 32
92: (77) r0 >>= 32
; if (bpf_probe_read_user(&data->buf, BUFSIZE, (void *)buf))
93: (55) if r0 != 0x0 goto pc+356
 R0_w=inv0 R6=invP0 R7=map_value(id=0,off=0,ks=4,vs=260,imm=0) R8=map_value(id=0,off=4,ks=4,vs=260,imm=0) R9=inv256 R10=fp0 fp-8=mmmmmmmm fp-16=mmmmmmmm fp-24=mmmmmmmm
94: (79) r2 = *(u64 *)(r10 -32)
invalid read from stack R10 off=-32 size=8
processed 593 insns (limit 1000000) max_states_per_insn 1 total_states 48 peak_states 48 mark_read 3

Traceback (most recent call last):
  File "/home/rongtao/Git/bcc/tools/./ttysnoop.py", line 236, in <module>
    b = BPF(text=bpf_text)
  File "/usr/lib/python3.9/site-packages/bcc/__init__.py", line 487, in __init__
    self._trace_autoload()
  File "/usr/lib/python3.9/site-packages/bcc/__init__.py", line 1455, in _trace_autoload
    fn = self.load_func(func_name, BPF.KPROBE)
  File "/usr/lib/python3.9/site-packages/bcc/__init__.py", line 526, in load_func
    raise Exception("Failed to load BPF program %s: %s" %
Exception: Failed to load BPF program b'kprobe__tty_write': Permission denied

ENV: LLVM 13.0.1, Kernel 5.15.67, aarch64

Overview of the error:

The verifier is unhappy, if '(r10 -32)' is not initialized, see also [0].

  $ sudo ./ttysnoop.py 10
  bpf: Failed to load program: Permission denied
  3: (7b) *(u64 *)(r10 -8) = r6
  4: (7b) *(u64 *)(r10 -16) = r6
  5: (7b) *(u64 *)(r10 -24) = r6
  6: (bf) r1 = r10
  ...
  91: (67) r0 <<= 32
  92: (77) r0 >>= 32
  ; if (bpf_probe_read_user(&data->buf, BUFSIZE, (void *)buf))
  93: (55) if r0 != 0x0 goto pc+356
  R0_w=inv0 R6=invP0 R7=map_value(id=0,off=0,ks=4,vs=260,imm=0) R8=map_value(
    id=0,off=4,ks=4,vs=260,imm=0) R9=inv256 R10=fp0 fp-8=mmmmmmmm
    fp-16=mmmmmmmm fp-24=mmmmmmmm
  94: (79) r2 = *(u64 *)(r10 -32)
  invalid read from stack R10 off=-32 size=8
  processed 593 insns (limit 1000000) max_states_per_insn 1 total_states 48
    peak_states 48 mark_read 3

This issue can also be resolved by upgrading LLVM>=14  and recompile and install
bcc.

[0] iovisor#2623

Signed-off-by: Rong Tao <[email protected]>
@yonghong-song
Copy link
Collaborator

Thanks for the fix. LGTM.

@yonghong-song yonghong-song merged commit 39b62cb into iovisor:master Feb 3, 2023
Rtoax added a commit to Rtoax/bcc that referenced this pull request Feb 10, 2023
The verifier is unhappy, if data struct _pad_ is not initialized, see [0][1].

    $ sudo ./nfsslower.py
    ...
    ; bpf_perf_event_output(ctx, (void *)bpf_pseudo_fd(1, -2), CUR_CPU_IDENTIFIER, &data, sizeof(data));
    83: (79) r1 = *(u64 *)(r10 -144)      ; R1_w=ctx(off=0,imm=0) R10=fp0
    84: (18) r3 = 0xffffffff              ; R3_w=4294967295
    86: (b7) r5 = 96                      ; R5_w=96
    87: (85) call bpf_perf_event_output#25
    invalid indirect read from stack R4 off -136+92 size 96
    processed 84 insns (limit 1000000) max_states_per_insn 0 total_states 4 peak_states 4 mark_read 4
    ...
    raise Exception("Failed to load BPF program %s: %s" %
    Exception: Failed to load BPF program b'raw_tracepoint__nfs_commit_done': Permission denied

[0] iovisor#2623
[1] iovisor#4453

Signed-off-by: Rong Tao <[email protected]>
chenhengqi pushed a commit that referenced this pull request Feb 11, 2023
The verifier is unhappy, if data struct _pad_ is not initialized, see [0][1].

    $ sudo ./nfsslower.py
    ...
    ; bpf_perf_event_output(ctx, (void *)bpf_pseudo_fd(1, -2), CUR_CPU_IDENTIFIER, &data, sizeof(data));
    83: (79) r1 = *(u64 *)(r10 -144)      ; R1_w=ctx(off=0,imm=0) R10=fp0
    84: (18) r3 = 0xffffffff              ; R3_w=4294967295
    86: (b7) r5 = 96                      ; R5_w=96
    87: (85) call bpf_perf_event_output#25
    invalid indirect read from stack R4 off -136+92 size 96
    processed 84 insns (limit 1000000) max_states_per_insn 0 total_states 4 peak_states 4 mark_read 4
    ...
    raise Exception("Failed to load BPF program %s: %s" %
    Exception: Failed to load BPF program b'raw_tracepoint__nfs_commit_done': Permission denied

[0] #2623
[1] #4453

Signed-off-by: Rong Tao <[email protected]>
captain5050 pushed a commit to captain5050/bcc that referenced this pull request Oct 12, 2023
The verifier is unhappy, if data struct _pad_ is not initialized, see [0][1].

    $ sudo ./nfsslower.py
    ...
    ; bpf_perf_event_output(ctx, (void *)bpf_pseudo_fd(1, -2), CUR_CPU_IDENTIFIER, &data, sizeof(data));
    83: (79) r1 = *(u64 *)(r10 -144)      ; R1_w=ctx(off=0,imm=0) R10=fp0
    84: (18) r3 = 0xffffffff              ; R3_w=4294967295
    86: (b7) r5 = 96                      ; R5_w=96
    87: (85) call bpf_perf_event_output#25
    invalid indirect read from stack R4 off -136+92 size 96
    processed 84 insns (limit 1000000) max_states_per_insn 0 total_states 4 peak_states 4 mark_read 4
    ...
    raise Exception("Failed to load BPF program %s: %s" %
    Exception: Failed to load BPF program b'raw_tracepoint__nfs_commit_done': Permission denied

[0] iovisor#2623
[1] iovisor#4453

Signed-off-by: Rong Tao <[email protected]>
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 this pull request may close these issues.

2 participants