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

bpf: read and copy proc exe at execve for matchBinaries #1926

Merged
merged 2 commits into from
Jan 11, 2024

Conversation

mtardy
Copy link
Member

@mtardy mtardy commented Jan 3, 2024

Fix for #1741

This PR changes how we read the binary path at execve time. We now read exe from the task_struct instead of relying upon the tracepoint argument that was just the path given to execve (thus possibly relative). This was an issue since matchBinaries could be avoided using relative links instead of absolute ones at execve.

For a future patch maybe:

In addition to this, we could also use this exe value for the binary path of the event. We also previously used the argument of execve, being possibly relative and corrected in userspace using cwd, but also possibly a symlink. This would thus introduce a user-facing change: tetragon events will now contain the canonical binary path while previously it could have been a symlink.

Without that user might try to "matchBinaries" a symlink file displayed in the Tetragon events and fail to make it work.

Preliminary work would be to make prepend_name work with 4096 (or MAX_PATH) buffer size.

@mtardy mtardy added area/bpf This is related to BPF code release-note/bug This PR fixes an issue in a previous release of Tetragon. labels Jan 3, 2024
@mtardy mtardy linked an issue Jan 4, 2024 that may be closed by this pull request
@mtardy mtardy force-pushed the pr/mtardy/fix-execve-path branch 4 times, most recently from 0bfffab to eeed60e Compare January 5, 2024 16:02
Copy link

netlify bot commented Jan 5, 2024

Deploy Preview for tetragon ready!

Name Link
🔨 Latest commit a0cb89e
🔍 Latest deploy log https://app.netlify.com/sites/tetragon/deploys/659e8373977004000892cf72
😎 Deploy Preview https://deploy-preview-1926--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.

@mtardy
Copy link
Member Author

mtardy commented Jan 10, 2024

Unfortunately, it looks like it doesn't fix for 4.19, I'll have to put it out for small progs kernels :/

This is needed for matchBinaries in the next commit. Previously we were
using the tracepoint argugement filename, which is potentially a
relative path.  This change has two main benefits: all paths checked
against matchBinaries will be absolutes and all symbolic links will be
resolved by the kernel.

Signed-off-by: Mahe Tardy <mahe.tardy@gmail.com>
Previously, filename from the args was copied into the execve_map, used
later for matchBinaries. With this change, we copy the absolute path we
read from the proc exe at the execve tracepoint stage to use it later.

Signed-off-by: Mahe Tardy <mahe.tardy@gmail.com>
@mtardy mtardy marked this pull request as ready for review January 10, 2024 17:43
@mtardy mtardy requested a review from a team as a code owner January 10, 2024 17:43
#define BINARY_PATH_MAX_LEN 256

struct heap_exe {
// because of verifier limitations, this has to be 2 * 256 bytes while 256
Copy link
Contributor

Choose a reason for hiding this comment

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

Is this true with large programs? We might be able to widen this some if we feel its an actual issue.

struct heap_exe {
// because of verifier limitations, this has to be 2 * 256 bytes while 256
// should be theoretically sufficient, and actually is, in unit tests.
char buf[BINARY_PATH_MAX_LEN * 2];
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 were a bit smarter this can be improved 2x waste of space. Over 256B though I don't care to do the work.

@jrfastab
Copy link
Contributor

OK lets try this. Merging I want to land this in a test cluster and play with it though so I'll do that shortly.

@jrfastab jrfastab merged commit 1a84735 into main Jan 11, 2024
35 checks passed
@jrfastab jrfastab deleted the pr/mtardy/fix-execve-path branch January 11, 2024 23:04
@tixxdz
Copy link
Member

tixxdz commented Jan 12, 2024

OK lets try this. Merging I want to land this in a test cluster and play with it though so I'll do that shortly.

So I wanted to suggest for security reasons and be bullet proof go inside https://github.com/cilium/tetragon/blob/main/bpf/process/bpf_execve_bprm_commit_creds.c#L47 using bprm->file

As it is now on the tracepoint hook is somehow late the window race is so small and I don't think it can be triggered to be honest, but I prefer no surprise ;-)
The allow_write_access(exec) https://elixir.bootlin.com/linux/latest/source/fs/exec.c#L1789 allows an fput on the file and even if there is some RCU lifetime on some fields of the file struct which are used to resolve the path, let's just ensure for this case that we do it properly under the right locks and avoid dereferencing pointers like that especially if this code is triggered by everyone, not to mention it is core logic of binary handling and we have safe easy alternative. The other suggestion on bprm->file is totally safe, the bprm is locked.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area/bpf This is related to BPF code release-note/bug This PR fixes an issue in a previous release of Tetragon.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Read absolute path for binary execution for matchBinaries
3 participants