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

Check a type of condition of if and ternary #1229

Merged
merged 6 commits into from
Apr 16, 2020

Conversation

mmisono
Copy link
Collaborator

@mmisono mmisono commented Mar 23, 2020

Some functions (e.g., exit()) return Type::none but if and ternary does not check it and that results in a NULL pointer dereference.

% sudo ./src/bpftrace -e 'k:f { exit() ? 0 : 0 }'
AddressSanitizer:DEADLYSIGNAL
=================================================================
==14010==ERROR: AddressSanitizer: SEGV on unknown address 0x000000000000 (pc 0x000000850854 bp 0x7fffffffa450 sp 0x7fffffffa180 T0)
==14010==The signal is caused by a READ memory access.
==14010==Hint: address points to the zero page.
    #0 0x850853 in bpftrace::ast::CodegenLLVM::visit(bpftrace::ast::Ternary&) /home/ubuntu/work/bpftrace/src/ast/codegen_llvm.cpp
    #1 0x861f29 in bpftrace::ast::CodegenLLVM::visit(bpftrace::ast::Probe&) /home/ubuntu/work/bpftrace/src/ast/codegen_llvm.cpp:1506:13
    #2 0x865256 in bpftrace::ast::CodegenLLVM::visit(bpftrace::ast::Program&) /home/ubuntu/work/bpftrace/src/ast/codegen_llvm.cpp:1597:12
    #3 0x86e34b in bpftrace::ast::CodegenLLVM::compile(bpftrace::DebugLevel, std::ostream&) /home/ubuntu/work/bpftrace/src/ast/codegen_llvm.cpp:2013:10
    #4 0x77623f in main /home/ubuntu/work/bpftrace/src/main.cpp:605:22
    #5 0x7fffee1451e2 in __libc_start_main /build/glibc-t7JzpG/glibc-2.30/csu/../csu/libc-start.c:308:16
    #6 0x4d1bcd in _start (/disk/work/bpftrace/build_san3/src/bpftrace+0x4d1bcd)

AddressSanitizer can not provide additional info.
SUMMARY: AddressSanitizer: SEGV /home/ubuntu/work/bpftrace/src/ast/codegen_llvm.cpp in bpftrace::ast::CodegenLLVM::visit(bpftrace::ast::Ternary&)
==1401

Fix this by checking a type of cond in the semantic analysis.

@mmisono
Copy link
Collaborator Author

mmisono commented Mar 23, 2020

CI failed due to the temporary connection error.

@fbs
Copy link
Member

fbs commented Mar 23, 2020

Looks like exit() is missing a check_assignment too

@mmisono
Copy link
Collaborator Author

mmisono commented Mar 25, 2020

Updates:

@fbs
Copy link
Member

fbs commented Mar 26, 2020

can you add some tests here too?

@mmisono mmisono mentioned this pull request Apr 5, 2020
@mmisono
Copy link
Collaborator Author

mmisono commented Apr 6, 2020

Updated.

  • Add tests

@fbs
Copy link
Member

fbs commented Apr 15, 2020

@mmisono could you rebase onto master? :)

mmisono added 5 commits April 16, 2020 19:31
Fix the following error.

```
% sudo ./src/bpftrace -e 'k:f { if(exit()){} }'
bpftrace: /usr/lib/llvm-9/include/llvm/Support/Casting.h:105: static bool llvm::isa_impl_cl<llvm::Constant, const llvm::Value *>::doit(const From *) [To = llvm::Constant, From = const llvm::Value *]: Assertion `Val && "isa<> used on a null pointer"' failed.
zsh: abort      sudo ./src/bpftrace -e 'k:f { if(exit()){} }'
```

The type of `exit()` is type::none.
Fix the following error.

```
% sudo ./src/bpftrace -e 'k:f { exit() ? 0 : 0 }'
AddressSanitizer:DEADLYSIGNAL
=================================================================
==14010==ERROR: AddressSanitizer: SEGV on unknown address 0x000000000000 (pc 0x000000850854 bp 0x7fffffffa450 sp 0x7fffffffa180 T0)
==14010==The signal is caused by a READ memory access.
==14010==Hint: address points to the zero page.
    #0 0x850853 in bpftrace::ast::CodegenLLVM::visit(bpftrace::ast::Ternary&) /home/ubuntu/work/bpftrace/src/ast/codegen_llvm.cpp
    bpftrace#1 0x861f29 in bpftrace::ast::CodegenLLVM::visit(bpftrace::ast::Probe&) /home/ubuntu/work/bpftrace/src/ast/codegen_llvm.cpp:1506:13
    bpftrace#2 0x865256 in bpftrace::ast::CodegenLLVM::visit(bpftrace::ast::Program&) /home/ubuntu/work/bpftrace/src/ast/codegen_llvm.cpp:1597:12
    bpftrace#3 0x86e34b in bpftrace::ast::CodegenLLVM::compile(bpftrace::DebugLevel, std::ostream&) /home/ubuntu/work/bpftrace/src/ast/codegen_llvm.cpp:2013:10
    bpftrace#4 0x77623f in main /home/ubuntu/work/bpftrace/src/main.cpp:605:22
    bpftrace#5 0x7fffee1451e2 in __libc_start_main /build/glibc-t7JzpG/glibc-2.30/csu/../csu/libc-start.c:308:16
    bpftrace#6 0x4d1bcd in _start (/disk/work/bpftrace/build_san3/src/bpftrace+0x4d1bcd)

AddressSanitizer can not provide additional info.
SUMMARY: AddressSanitizer: SEGV /home/ubuntu/work/bpftrace/src/ast/codegen_llvm.cpp in bpftrace::ast::CodegenLLVM::visit(bpftrace::ast::Ternary&)
==14010==ABORTING
```
This prevents to store a return value of exit() in a variable and a map.
Currently, Type::array value cannot be assigned to a map and a variable.
Check it in the semantic analysis.
This prevents the error like the follwing:

```
% sudo ASAN_OPTIONS=detect_leaks=0 ./src/bpftrace -e 'BEGIN { @ = max(exit()); }'
AddressSanitizer:DEADLYSIGNAL
=================================================================
==25253==ERROR: AddressSanitizer: SEGV on unknown address 0x000000000000 (pc 0x00000089e3dc bp 0x7fff0bf07270 sp 0x7fff0bf07270 T0)
==25253==The signal is caused by a READ memory access.
==25253==Hint: address points to the zero page.
    #0 0x89e3dc in llvm::Value::getType() const /usr/lib/llvm-10/include/llvm/IR/Value.h:246:34
    bpftrace#1 0x89cd6e in llvm::IRBuilder<llvm::ConstantFolder, llvm::IRBuilderDefaultInserter>::CreateIntCast(llvm::Value*, llvm::Type*, bool, llvm::Twine const&) /usr/lib/llvm-10/include/llvm/IR/IRBuilder.h:2172:12
    bpftrace#2 0x889ad5 in bpftrace::ast::CodegenLLVM::visit(bpftrace::ast::Call&) /home/ubuntu/work/bpftrace/bpftrace/src/ast/codegen_llvm.cpp:328:16
    bpftrace#3 0x880160 in bpftrace::ast::Call::accept(bpftrace::ast::Visitor&) /home/ubuntu/work/bpftrace/bpftrace/src/ast/ast.cpp:129:5
    bpftrace#4 0x8966c0 in bpftrace::ast::CodegenLLVM::visit(bpftrace::ast::AssignMapStatement&) /home/ubuntu/work/bpftrace/bpftrace/src/ast/codegen_llvm.cpp:1315:20
    bpftrace#5 0x880fa3 in bpftrace::ast::AssignMapStatement::accept(bpftrace::ast::Visitor&) /home/ubuntu/work/bpftrace/bpftrace/src/ast/ast.cpp:284:5
    bpftrace#6 0x897a70 in bpftrace::ast::CodegenLLVM::visit(bpftrace::ast::Probe&) /home/ubuntu/work/bpftrace/bpftrace/src/ast/codegen_llvm.cpp:1510:13
    bpftrace#7 0x8815f3 in bpftrace::ast::Probe::accept(bpftrace::ast::Visitor&) /home/ubuntu/work/bpftrace/bpftrace/src/ast/ast.cpp:355:5
    bpftrace#8 0x89895b in bpftrace::ast::CodegenLLVM::visit(bpftrace::ast::Program&) /home/ubuntu/work/bpftrace/bpftrace/src/ast/codegen_llvm.cpp:1601:12
    bpftrace#9 0x8816a3 in bpftrace::ast::Program::accept(bpftrace::ast::Visitor&) /home/ubuntu/work/bpftrace/bpftrace/src/ast/ast.cpp:364:5
    bpftrace#10 0x89b397 in bpftrace::ast::CodegenLLVM::compile(bpftrace::DebugLevel, std::ostream&) /home/ubuntu/work/bpftrace/bpftrace/src/ast/codegen_llvm.cpp:2019:10
    bpftrace#11 0x813f3c in main /home/ubuntu/work/bpftrace/bpftrace/src/main.cpp:589:22
    bpftrace#12 0x7f2794c4db96 in __libc_start_main /build/glibc-OTsEL5/glibc-2.27/csu/../csu/libc-start.c:310
    bpftrace#13 0x5c64c9 in _start (/home/ubuntu/work/bpftrace/bpftrace/build_llvm10/src/bpftrace+0x5c64c9)

AddressSanitizer can not provide additional info.
SUMMARY: AddressSanitizer: SEGV /usr/lib/llvm-10/include/llvm/IR/Value.h:246:34 in llvm::Value::getType() const
==25253==ABORTING
```
The size of ternary is 8 for integer, but it is possible that lhs and
rhs have smaller bit-width integer. Fix this by casting.

This fixes the following error.

```
% sudo ./src/bpftrace -e 'k:f { @ = 1 ? (int8)1 : 0; }' -v
BTF: using data from /sys/kernel/btf/vmlinux
Attaching 1 probe...

Error log:
0: (b7) r1 = 1
1: (73) *(u8 *)(r10 -8) = r1
2: (b7) r1 = 0
3: (7b) *(u64 *)(r10 -16) = r1
last_idx 3 first_idx 0
regs=2 stack=0 before 2: (b7) r1 = 0
4: (18) r1 = 0xffff8c3293778000
6: (bf) r2 = r10
7: (07) r2 += -16
8: (bf) r3 = r10
9: (07) r3 += -8
10: (b7) r4 = 0
11: (85) call bpf_map_update_elem#2
invalid indirect read from stack off -8+1 size 8
processed 11 insns (limit 1000000) max_states_per_insn 0 total_states 0 peak_states 0 mark_read 0

Error loading program: kprobe:f
```
@mmisono
Copy link
Collaborator Author

mmisono commented Apr 16, 2020

Rebased. I also added the fix for #1222 (comment).

@fbs fbs merged commit 524bf5a into bpftrace:master Apr 16, 2020
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