-
-
Notifications
You must be signed in to change notification settings - Fork 1.4k
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
Fix several undefined behaviors #1645
Conversation
src/ast/semantic_analyser.cpp
Outdated
long value = static_cast<Integer &>(size_arg).n; | ||
if (value < 0) | ||
auto integer = dynamic_cast<Integer *>(&size_arg); | ||
if (integer) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this check was wrong to begin with. We should only be downcasting and checking the value after we know it's a literal, right? Otherwise we could be reading junk. So in a is_final_pass()
branch and after the check_arg()
. Same for the buf
case. I believe that would solve this static_cast issue as well.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That makes sense. But I found in the case of buf(), the length (buffer_size) is used in other places, and we cannot check the length in the final pass.. So I decided to use dynamic_cast here. 735b944 please let me know if there is a better way.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can't buf() just use max_buffer_size
until the final pass? Then on the final pass it can do all the error checks and calculations.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I first tried it and failed. Then I realized that AssignMap did not update the map size. I fixed it and now I think it's OK: bfded77
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is update_assign_map_type() fixing a separate issue? I'm not seeing why it's related.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
without it, https://github.com/iovisor/bpftrace/blob/7ca62cb0aca9d6125d8a96fdc0238f7e07354097/src/ast/semantic_analyser.cpp#L2067 is failed because it thinks map size is max_buffer_size
, but expr_size
become smaller in the final pass.
a61be2f
to
a4cd32b
Compare
src/ast/semantic_analyser.cpp
Outdated
@@ -604,7 +604,7 @@ void SemanticAnalyser::visit(Call &call) | |||
} | |||
} | |||
|
|||
if (call.vargs->size() == 2) | |||
if (is_final_pass() && call.vargs->size() == 2) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think you have to check the type before the downcast otherwise you don't know what you're casting
if (is_final_pass() && call.vargs->size() == 2) | |
if (is_final_pass() && check_arg(..) && call.vargs->size() == 2) |
And then delete the check_arg()
below
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see. I missed the check_arg()
below. thanks.
a4cd32b
to
b6e5ecb
Compare
UBSan detected the following error. ``` % sudo /src/bpftrace -e 'BEGIN { @ = -9223372036854775808 }' src/parser.yy:297:81: runtime error: signed integer overflow: -1 * -9223372036854775808 cannot be represented in type 'long' SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior src/parser.yy:297:81 in Attaching 1 probe... ^C @: -9223372036854775808 ``` -9223372036854775808 is LONG_MIN, but when creating ast::Integer, we multiply the value by -1, and this is the cause of the error. To avoid this error, we can manually calculate negative number like the following: ``` (long)(~(unsigned long)($2) + 1) ``` Note that a minus LONG_MIN is LONG_MIN. ``` % ./src/bpftrace -e 'BEGIN { $x = -9223372036854775808; printf("%ld\n", -$x); } ' Attaching 1 probe... -9223372036854775808 ^C ``` To cope with this, we need a runtime overflow checker.
b6e5ecb
to
fa2c2ab
Compare
hmm.. still there are some dowancast issues
|
the problem is Type::integer does not necessarily mean that is ast::Integer. |
ah, sorry I forgot about |
UBSan reports the following error when running bpftrace_test. ``` /work/bpftrace2/src/ast/semantic_analyser.cpp:662:22: runtime error: downcast of address 0x7fffe80cced0 which does not point to an object of type 'bpftrace::ast::Integer' 0x7fffe80cced0: note: object is of type 'bpftrace::ast::String' 00 00 00 00 a8 fa 4b 01 00 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 16 00 00 00 00 00 00 00 ^~~~~~~~~~~~~~~~~~~~~~~ vptr for 'bpftrace::ast::String' ``` the problem test is ``` test("kprobe:f { str(arg0, \"hello\"); }", 10) ``` and the program tries to downcast "hello" to ast::Integer. To fix this, do static cast only in the final pss. In the final pass we know it's a integer literal by check_arg().
UBSan reports the following error. ``` % sudo ./src/bpftrace -e 'BEGIN { @ = lhist(pid, 0, 100, 1); }' /work/bpftrace2/src/ast/codegen_llvm.cpp:462:26: runtime error: downcast of address 0x611000002d40 which does not point to an object of type 'bpftrace::ast::Integer' 0x611000002d40: note: object is of type 'bpftrace::ast::Builtin' 08 00 80 7e a8 a6 39 01 00 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 0d 00 00 00 00 00 00 00 ^~~~~~~~~~~~~~~~~~~~~~~ vptr for 'bpftrace::ast::Builtin' ``` There is no need to static cast to Integer, so simply remove them.
fa2c2ab
to
1557f74
Compare
UBSan (Undefined Behavior Sanitizer) found several errors when running bpftrace_test. This commits fix them.
Please see the commit messages for the details.
Checklist
docs/reference_guide.md
CHANGELOG.md