-
Notifications
You must be signed in to change notification settings - Fork 384
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
Postfix operator for matchBinaries selector #2689
Conversation
✅ Deploy Preview for tetragon ready!
To edit notification comments on pull requests, go to your Netlify site configuration. |
cd3bbdf
to
35f46a1
Compare
72ffd1a
to
3ad08ce
Compare
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.
Thanks that's a great addition! Would love an ack from Kev since we are touching a few bits of its STRING code.
My main nit would be to add a test using the perfring framework to check for a missing event so that we are sure this thing works as intended, and I'm good! :)
|
||
The `values` field has to be a map of `strings`. The default behaviour | ||
is `followForks: true`, so all the child processes are followed. | ||
The current limitation is 4 values. |
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 the limitation here is outdated but it's out of the scope of this PR
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 we need to store the last 128 chars of the binary path in execve_send (bpf/process/bpf_execve_event.c) in a new part of the struct binary, specifically for postfix matching.
I think we need a copy of copy_reverse() (called file_copy_reverse()) that only copies file paths from buffer expected to be BINARY_PATH_MAX_LENGTH in size, leaving the original with the PATH_MASK position masking.
Thanks kev I completely overlooked this previous struggle. Indeed, for the binary we don't store the whole path so you have a few cases to take into account:
|
Personally, I'd always copy the end into the new end slot to save extra logic when matching. I agree that you should lazily reverse it the first time you do a postfix match on it, but this has race conditions. I think the simple solution (not necessarily the cheapest or best) is to have two extra slots, not one extra slot! So struct binary could look like:
On execution, copy the end of the path into end. On first postfix lookup, reverse end into end_r and set reversed to true. If another thread is doing the same then end will be unaffected, so end_r will end up with the same values, even if one thread is still reversing end into end_r while another is using end_r. If reversed is true, then just match on end_r and assume it has already been reversed. |
Thanks for such detailed advice! I'll try to implement the logic you described. |
Remember that they are challenges for long path
I just remember I had a very early draft branch from October but I don't think it'll really help you here, it was similar to the advice given here. |
3ad08ce
to
7c5d21c
Compare
8eb0a5b
to
a156bb0
Compare
@mtardy , @kevsecurity , guys, can I ask you to review again, please? |
sure, note that you can use that btw even if a message is fine of course. |
a156bb0
to
ab86ce6
Compare
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.
Thanks a lot for those updates :), here are some comments. My main point would be to add a test with a long binary like in 67348f6 so that we make sure this PR works and doesn't break.
It's looking good. Address the few things including some tests and we should be good to merge. |
8e4afae
to
a750259
Compare
0e5788f
to
b439d09
Compare
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.
LGTM
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.
Thanks, it's almost ready, the only small blocker for me is to have a first commit that compiles & runs (the struct should be synchronized between kernel/user), the rest is nits and followups.
__u64 revlen = event->exe.len; | ||
|
||
if (event->exe.len > STRING_POSTFIX_MAX_LENGTH - 1) | ||
revlen = STRING_POSTFIX_MAX_LENGTH - 1; |
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.
nit: you could also write revlen
into the struct so that you don't need to recompute it again, not sure it's better than this but you could downsize again here and use 16/16 bytes, so that you get path_len
and end_len
/rev_len
?
// if end_r contains reversed path postfix
__u32 reversed;
Adding postfix/notpostfix cases to match_binaries function allows to support postfix operator in matchBinaries selector. Modifying 'binary' struct to hold path postfix. Signed-off-by: Andrei Fedotov <[email protected]>
Adding Postifx and NotPostfix operators to matchBinaries selector as it already done for matchArgs selector. Signed-off-by: Andrei Fedotov <[email protected]>
Adding tests for Postix and NotPostfix operators in TestKprobeMatchBinaries and TestKprobeMatchBinariesPerfring. Adding TestKprobeMatchBinariesLargePath test. Signed-off-by: Andrei Fedotov <[email protected]>
Signed-off-by: Andrei Fedotov <[email protected]>
b439d09
to
6cdfbd4
Compare
@mtardy , I think now it's ready:) |
Yep thanks again, let's merge this! 🌮 🎉 |
Details can be found in #2679.