-
Notifications
You must be signed in to change notification settings - Fork 376
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
matchBinaries: support followChildren #2720
Conversation
✅ Deploy Preview for tetragon ready!
To edit notification comments on pull requests, go to your Netlify site configuration. |
4e4f81f
to
6424ce1
Compare
@@ -11,7 +11,8 @@ | |||
|
|||
#define ENAMETOOLONG 36 /* File name too long */ | |||
|
|||
#define MAX_BUF_LEN 256 | |||
#define MATCH_BINARIES_PATH_MAX_LENGTH 256 |
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.
Do these lengths present a problem in terms of potential truncation?
while any path fragment can only be 255, the total path could be larger.
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.
MATCH_BINARIES_PATH_MAX
is the size of the paths users can specify in values
under MatchBinaries
. That is, it only limits the size of the user-specified paths that we want to match against.
For example,
- matchBinaries:
- operator: "In"
values:
- "/usr/bin/bash"
would work, but:
- matchBinaries:
- operator: "In"
values:
- "/foo/foo/foo/foo/foo/foo/foo/foo/foo/foo/foo/foo/foo/foo/foo/foo/foo/foo/foo/foo/foo/foo/foo/foo/foo/foo/foo/foo/foo/foo/foo/foo/foo/foo/foo/foo/foo/foo/foo/foo/foo/foo/foo/foo/foo/foo/foo/foo/foo/foo/foo/foo/foo/foo/foo/foo/foo/foo/foo/foo/foo/foo/foo/foo"
wouldn't.
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.
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.
Yap, I've also thought the same :)
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.
so this is an issue on the prefix feature because of the way we read dentries, since we read them from end to start, you can escape a prefix match using a long path (>256). There are attempts to fix at the moment (#2718) but the only durable fix would be to extend MATCH_BINARIES_PATH_MAX_LENGTH
to 4096 somehow.
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.
If we ifdef'd into 6.x kernels maybe 4096 is fine with better BPF? This way limitation only exists on <X.Y versions?
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.
So I've been trying to extend the length to 4096, mostly making prepend_name (the function we use to read dentry) to support 4096 chars and I'm currently blocked when the compiler is replacing memset
and memcpy
when the object (from a map value) is too large.
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 cool feature!
I think my main point would be to make things a bit easier to understand as:
- it's not easy to link the
mbset
naming to the follow children match binaries feature. - sometimes what we do in BPF can look a bit cryptic when it could be explained.
I think I understood the patch after taking a bit of time, but it might get complicated to get it in some time without more comments/better naming.
@@ -1520,6 +1520,7 @@ FUNC_INLINE size_t type_to_min_size(int type, int argm) | |||
struct match_binaries_sel_opts { | |||
__u32 op; | |||
__u32 map_id; | |||
__u32 mbset_id; |
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.
not a big fan of the naming here given it's already in the match binary selector option and it does not stand out that it's for the follow children feature. In general I think mbset
for match binaries set does not give a strong idea it's behind the "follow children" feature.
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 have a different opinion. The mechanism is a matchBinaries set (mbset
) and is used to implement the followChidren
feature. I prefer to name things based on what they are rather than how they are used. Note that the latter can change. In any case, I'm happy to change it. What would be your suggestion of a better name?
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, just added some small comments.
6424ce1
to
7d5d536
Compare
Thanks for the reviews, pushed a new version to address the feedback. |
checkpatch complains with:
But we do not seem to have support for it:
|
This is out of the scope of this PR and I don't want to block it on that but we could add what Cilium does in our compiler.h: https://github.com/cilium/cilium/blob/b189c578ea4da02467dc636e338683b8b6b4b012/bpf/include/bpf/compiler.h#L113-L115 |
Signed-off-by: Kornilios Kourtis <[email protected]>
Signed-off-by: Kornilios Kourtis <[email protected]>
Move MATCH_BINARIES_PATH_MAX_LENGTH to bpf_process_event.h so that it can be used in the exec hook in subsequent patches. Signed-off-by: Kornilios Kourtis <[email protected]>
The goal is to implement a 'followChildren: true' attribute in the MatchBinaries operator that can be used to match not only processes with the specified binary name, but also their children. To do so, we need to mark processes at exec time. This patch introduces tha bpf map that will be used for the marking. The map has paths as keys and a bitset of ids as a value. The map is written by user-space and read in BPF. Each id corresponds to a MatchBinaries section with 'followChildren: true'. The mbset package implements the user-space side of the map. For example, consider the following sections: - matchBinaries: - operator: "In" values: - "/usr/bin/bash" - "/usr/bin/dash" followChildren: true ID: 0 - matchBinaries: - operator: "In" values: - "/usr/bin/bash" - "/usr/bin/csh" followChildren: true ID: 5 The map then will look like: /usr/bin/bash -> (1<<0) | (1<<5) = 0x21 /usr/bin/dash -> (1<<0) = 0x1 /usr/bin/csh -> (1<<5) = 0x20 Signed-off-by: Kornilios Kourtis <[email protected]>
This patch initialized the tg_mbset_map based on MatchBinaries sections. An id is allocated when the we parse the section. Subsequently, we update the given id for the patches specified in the section. Signed-off-by: Kornilios Kourtis <[email protected]>
This commit adds an mb_bitset field in the binary structure. The filed is set in the exec hook using the parent bitset and the contents of the tg_mbset_map. Note that in bpf_fork, we memcpy the old binary so the bitset will be propageted to children. Signed-off-by: Kornilios Kourtis <[email protected]>
7d5d536
to
5715e16
Compare
Make sense, added |
This is going to be used in the next patch. Signed-off-by: Kornilios Kourtis <[email protected]>
This commit adds a check in match_binaries that uses the bitset that is tracked from parent to children, allowing to track children of a given binary. Signed-off-by: Kornilios Kourtis <[email protected]>
CopyFileToTmp copies a file to /tmp and returns its name. It also chmods the destination file, so it can be used to copy binaries. It's going to be used the next patch. Signed-off-by: Kornilios Kourtis <[email protected]>
loadGenericSensorTest is a helper function to load a generic sensor. With the addition of the tg_mbset_map in the previous commits, when using a matchBinaries with followChildren: true because for the latter, we need to base sensor to be loaded. This fixes the above issue by initializing the base (exec) sensor before running SensorsFromPolicy. Signed-off-by: Kornilios Kourtis <[email protected]>
The test copies /bin/sh into a temp location and Creates a policy that mathes the temp sh and its children. It executes the getcpu program and checks that the policy caught the syscall. Signed-off-by: Kornilios Kourtis <[email protected]>
5715e16
to
dc2d413
Compare
@kkourt I see |
This PR introduces a
FollowChildren:
attribute inMatchBinaries
.For now, only the
In
operator is supported but others can be added.Another limitation is that only 64 of such sections are supported, but this number can also be increased.