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

matchBinaries: support followChildren #2720

Merged
merged 11 commits into from
Aug 5, 2024
Merged

Conversation

kkourt
Copy link
Contributor

@kkourt kkourt commented Jul 23, 2024

This PR introduces a FollowChildren: attribute in MatchBinaries.
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.

tracing: introduce FollowChildren attribute in MatchBinaries selector

@kkourt kkourt added the release-note/minor This PR introduces a minor user-visible change label Jul 23, 2024
Copy link

netlify bot commented Jul 23, 2024

Deploy Preview for tetragon ready!

Name Link
🔨 Latest commit 5715e16
🔍 Latest deploy log https://app.netlify.com/sites/tetragon/deploys/66af330573551f00083a88aa
😎 Deploy Preview https://deploy-preview-2720--tetragon.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify site configuration.

@kkourt kkourt force-pushed the pr/kkourt/matchbin-follow branch 3 times, most recently from 4e4f81f to 6424ce1 Compare July 24, 2024 09:38
@kkourt kkourt marked this pull request as ready for review July 24, 2024 10:34
@kkourt kkourt requested a review from a team as a code owner July 24, 2024 10:34
@kkourt kkourt requested a review from tpapagian July 24, 2024 10:34
@@ -11,7 +11,8 @@

#define ENAMETOOLONG 36 /* File name too long */

#define MAX_BUF_LEN 256
#define MATCH_BINARIES_PATH_MAX_LENGTH 256
Copy link

@vparla vparla Jul 24, 2024

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.

Copy link
Contributor Author

@kkourt kkourt Jul 25, 2024

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.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for this work @kkourt! This will help us out immensely.

One comment, could we in the future perhaps convert this to use the same string handling as was added in #2069 ? Not for now, just in the future.

Copy link
Contributor Author

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 :)

Copy link
Member

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.

Copy link
Contributor

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?

Copy link
Member

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.

@mtardy mtardy self-requested a review July 29, 2024 09:10
Copy link
Member

@mtardy mtardy left a 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:

  1. it's not easy to link the mbset naming to the follow children match binaries feature.
  2. 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.

bpf/process/bpf_execve_event.c Show resolved Hide resolved
pkg/selectors/kernel.go Outdated Show resolved Hide resolved
@@ -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;
Copy link
Member

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.

Copy link
Contributor Author

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?

bpf/process/bpf_execve_event.c Outdated Show resolved Hide resolved
bpf/process/bpf_execve_event.c Outdated Show resolved Hide resolved
bpf/process/bpf_execve_event.c Outdated Show resolved Hide resolved
bpf/process/types/basic.h Show resolved Hide resolved
pkg/testutils/copyfile.go Show resolved Hide resolved
pkg/sensors/tracing/matchbinaries_follow_children_test.go Outdated Show resolved Hide resolved
Copy link
Member

@tpapagian tpapagian left a 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.

bpf/process/bpf_execve_event.c Show resolved Hide resolved
pkg/mbset/mbset.go Outdated Show resolved Hide resolved
pkg/sensors/tracing/matchbinaries_follow_children_test.go Outdated Show resolved Hide resolved
pkg/sensors/tracing/matchbinaries_follow_children_test.go Outdated Show resolved Hide resolved
pkg/sensors/tracing/matchbinaries_follow_children_test.go Outdated Show resolved Hide resolved
@kkourt kkourt force-pushed the pr/kkourt/matchbin-follow branch from 6424ce1 to 7d5d536 Compare July 31, 2024 09:44
@kkourt kkourt requested review from olsajiri and mtardy July 31, 2024 09:44
@kkourt
Copy link
Contributor Author

kkourt commented Jul 31, 2024

Thanks for the reviews, pushed a new version to address the feedback.

@kkourt
Copy link
Contributor Author

kkourt commented Jul 31, 2024

checkpatch complains with:

  Warning: WARNING:PREFER_FALLTHROUGH: Prefer 'fallthrough;' over fallthrough comment

But we do not seem to have support for it:

process/types/basic.h:1588:4: error: use of undeclared identifier 'fallthrough'                                                                                                                                                                                
                        fallthrough; 

@mtardy
Copy link
Member

mtardy commented Aug 1, 2024

checkpatch complains with:

  Warning: WARNING:PREFER_FALLTHROUGH: Prefer 'fallthrough;' over fallthrough comment

But we do not seem to have support for it:

process/types/basic.h:1588:4: error: use of undeclared identifier 'fallthrough'                                                                                                                                                                                
                        fallthrough; 

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

pkg/mbset/mbset.go Outdated Show resolved Hide resolved
kkourt added 6 commits August 4, 2024 09:50
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]>
@kkourt kkourt force-pushed the pr/kkourt/matchbin-follow branch from 7d5d536 to 5715e16 Compare August 4, 2024 07:51
@kkourt
Copy link
Contributor Author

kkourt commented Aug 4, 2024

checkpatch complains with:

  Warning: WARNING:PREFER_FALLTHROUGH: Prefer 'fallthrough;' over fallthrough comment

But we do not seem to have support for it:

process/types/basic.h:1588:4: error: use of undeclared identifier 'fallthrough'                                                                                                                                                                                
                        fallthrough; 

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

Make sense, added fallthrough.

kkourt added 2 commits August 4, 2024 09:52
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]>
kkourt added 3 commits August 4, 2024 09:52
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]>
@kkourt kkourt force-pushed the pr/kkourt/matchbin-follow branch from 5715e16 to dc2d413 Compare August 4, 2024 07:53
@kkourt kkourt merged commit 848a38a into main Aug 5, 2024
46 checks passed
@kkourt kkourt deleted the pr/kkourt/matchbin-follow branch August 5, 2024 11:01
@lambdanis
Copy link
Contributor

lambdanis commented Aug 9, 2024

@kkourt I see followChildren is a required field in CRD - that's a breaking change and breaks existing policies. Can we make it not required and default to false?

@kkourt
Copy link
Contributor Author

kkourt commented Aug 10, 2024

@kkourt I see followChildren is a required field in CRD - that's a breaking change and breaks existing policies. Can we make it not required and default to false?

Good point: #2790

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
release-note/minor This PR introduces a minor user-visible change
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants