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

update(sinsp): handle (deleted) in userspace #2151

Merged
merged 2 commits into from
Nov 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 0 additions & 26 deletions driver/ppm_fillers.c
Original file line number Diff line number Diff line change
Expand Up @@ -1468,19 +1468,6 @@ int f_proc_startupdate(struct event_filler_arguments *args) {
fput(exe_file);
}

/* The trusted_exepath could end with the suffix " (deleted)".
* https://github.com/torvalds/linux/blob/2dde18cd1d8fac735875f2e4987f11817cc0bc2c/fs/d_path.c#L255
* This is unhandy to manage in userspace, for this reason, we can remove it here
*/
if(trusted_exepath != NULL) {
char deleted_suffix[] = " (deleted)";
int diff_len = strlen(trusted_exepath) - strlen(deleted_suffix);
if(diff_len > 0 &&
(strncmp(&trusted_exepath[diff_len], deleted_suffix, sizeof(deleted_suffix)) == 0)) {
trusted_exepath[diff_len] = '\0';
}
}

if(exe_writable) {
flags |= PPM_EXE_WRITABLE;
}
Expand Down Expand Up @@ -7358,19 +7345,6 @@ int f_sched_prog_exec(struct event_filler_arguments *args) {
fput(exe_file);
}

/* The trusted_exepath could end with the suffix " (deleted)".
* https://github.com/torvalds/linux/blob/2dde18cd1d8fac735875f2e4987f11817cc0bc2c/fs/d_path.c#L255
* This is unhandy to manage in userspace, for this reason, we can remove it here
*/
if(trusted_exepath != NULL) {
char deleted_suffix[] = " (deleted)";
int diff_len = strlen(trusted_exepath) - strlen(deleted_suffix);
if(diff_len > 0 &&
(strncmp(&trusted_exepath[diff_len], deleted_suffix, sizeof(deleted_suffix)) == 0)) {
trusted_exepath[diff_len] = '\0';
}
}

if(exe_writable) {
flags |= PPM_EXE_WRITABLE;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -241,11 +241,9 @@ TEST(GenericTracepoints, sched_proc_exec_success_memfd) {
/* Parameter 28: trusted_exepath (type: PT_FSPATH) */
/* In the kmod, we use the "d_path" helper while in BPF we reconstruct the path
* by hand so the result is a little bit different.
* Please note that in the kernel module, we remove the " (deleted)" suffix while
* in BPF we don't add it at all.
*/
if(evt_test->is_kmod_engine()) {
evt_test->assert_charbuf_param(28, "/memfd:malware");
evt_test->assert_charbuf_param(28, "/memfd:malware (deleted)");
} else {
/* In BPF drivers we don't have the correct result but we can reconstruct part of it */
evt_test->assert_charbuf_param(28, "memfd:malware");
Expand Down
4 changes: 1 addition & 3 deletions test/drivers/test_suites/syscall_exit_suite/execve_x.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -912,11 +912,9 @@ TEST(SyscallExit, execveX_success_memfd) {
/* Parameter 28: trusted_exepath (type: PT_FSPATH) */
/* In the kmod, we use the "d_path" helper while in BPF we reconstruct the path
* by hand so the result is a little bit different.
* Please note that in the kernel module, we remove the " (deleted)" suffix while
* in BPF we don't add it at all.
*/
if(evt_test->is_kmod_engine()) {
evt_test->assert_charbuf_param(28, "/memfd:malware");
evt_test->assert_charbuf_param(28, "/memfd:malware (deleted)");
} else {
/* In BPF drivers we don't have the correct result but we can reconstruct part of it */
evt_test->assert_charbuf_param(28, "memfd:malware");
Expand Down
4 changes: 1 addition & 3 deletions test/drivers/test_suites/syscall_exit_suite/execveat_x.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -707,11 +707,9 @@ TEST(SyscallExit, execveatX_success_memfd) {
/* Parameter 28: trusted_exepath (type: PT_FSPATH) */
/* In the kmod, we use the "d_path" helper while in BPF we reconstruct the path
* by hand so the result is a little bit different.
* Please note that in the kernel module, we remove the " (deleted)" suffix while
* in BPF we don't add it at all.
*/
if(evt_test->is_kmod_engine()) {
evt_test->assert_charbuf_param(28, "/memfd:malware");
evt_test->assert_charbuf_param(28, "/memfd:malware (deleted)");
} else {
/* In BPF drivers we don't have the correct result but we can reconstruct part of it */
evt_test->assert_charbuf_param(28, "memfd:malware");
Expand Down
9 changes: 4 additions & 5 deletions userspace/libsinsp/parsers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1289,7 +1289,7 @@ void sinsp_parser::parse_clone_exit_caller(sinsp_evt *evt, int64_t child_tid) {
/* Take some further info from the caller */
if(valid_caller) {
/* We should trust the info we obtain from the caller, if it is valid */
child_tinfo->m_exepath = caller_tinfo->m_exepath;
child_tinfo->set_exepath(std::string(caller_tinfo->m_exepath));

child_tinfo->m_exe_writable = caller_tinfo->m_exe_writable;

Expand Down Expand Up @@ -1604,7 +1604,7 @@ void sinsp_parser::parse_clone_exit_child(sinsp_evt *evt) {
* enrichment...
*/

child_tinfo->m_exepath = lookup_tinfo->m_exepath;
child_tinfo->set_exepath(std::string(lookup_tinfo->m_exepath));

child_tinfo->m_exe_writable = lookup_tinfo->m_exe_writable;

Expand Down Expand Up @@ -2089,8 +2089,7 @@ void sinsp_parser::parse_execve_exit(sinsp_evt *evt) {
*/

/* Parameter 28: trusted_exepath (type: PT_FSPATH) */
parinfo = evt->get_param(27);
evt->get_tinfo()->m_exepath = parinfo->m_val;
evt->get_tinfo()->set_exepath(evt->get_param(27)->as<std::string>());
} else {
/* ONLY VALID FOR OLD SCAP-FILES:
* In older event versions we can only rely on our userspace reconstruction
Expand Down Expand Up @@ -2191,7 +2190,7 @@ void sinsp_parser::parse_execve_exit(sinsp_evt *evt) {
fullpath = sinsp_utils::concatenate_paths(sdir, pathname);
}
}
evt->get_tinfo()->m_exepath = fullpath;
evt->get_tinfo()->set_exepath(std::move(fullpath));
}
}

Expand Down
55 changes: 55 additions & 0 deletions userspace/libsinsp/test/classes/sinsp_threadinfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -128,3 +128,58 @@ TEST_F(sinsp_with_test_input, THRD_INFO_assign_children_to_a_nullptr) {
ASSERT_THREAD_CHILDREN(p2_t1_tid, 0, 0);
ASSERT_THREAD_INFO_PIDS(p3_t1_tid, p3_t1_pid, 0);
}

TEST(sinsp_threadinfo, set_exepath) {
auto tinfo = std::make_shared<sinsp_threadinfo>();

{
// Nothing changes
std::string path = "no_suffix (del)";
size_t before_len = path.size();
tinfo->set_exepath(std::move(path));
ASSERT_EQ(tinfo->get_exepath().size(), before_len);
}

{
// Truncate it
std::string path = "no_suffix (deleted)";
size_t before_len = path.size();
tinfo->set_exepath(std::move(path));
ASSERT_NE(tinfo->get_exepath().size(), before_len);
ASSERT_EQ(tinfo->get_exepath(), "no_suffix");
}

{
// Nothing changes (this is not possible from the kernel)
std::string path = "no_suffix(deleted)";
size_t before_len = path.size();
tinfo->set_exepath(std::move(path));
ASSERT_EQ(tinfo->get_exepath().size(), before_len);
}

{
// Nothing changes (this is not possible from the kernel)
std::string path = "(deleted)";
size_t before_len = path.size();
tinfo->set_exepath(std::move(path));
ASSERT_EQ(tinfo->get_exepath().size(), before_len);
}

{
// Nothing changes (this is not possible from the kernel)
std::string path = " (deleted)";
size_t before_len = path.size();
tinfo->set_exepath(std::move(path));
ASSERT_EQ(tinfo->get_exepath().size(), before_len);
}

{
// Truncate it, please note that a double space from the kernel is not possible but here we
// just want to test it.
std::string path = "a (deleted)";
size_t before_len = path.size();
tinfo->set_exepath(std::move(path));
ASSERT_NE(tinfo->get_exepath().size(), before_len);
ASSERT_EQ(tinfo->get_exepath(), "a ");
}
}
18 changes: 10 additions & 8 deletions userspace/libsinsp/test/filterchecks/proc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -67,14 +67,16 @@ TEST_F(sinsp_with_test_input, PROC_FILTER_exepath) {
DEFAULT_TREE

/* Now we call an execve on p6_t1 */
auto evt = generate_execve_enter_and_exit_event(0,
p6_t1_tid,
p6_t1_tid,
p6_t1_pid,
p6_t1_ptid,
"/good-exe",
"good-exe",
"/usr/bin/bad-exe");
auto evt =
generate_execve_enter_and_exit_event(0,
p6_t1_tid,
p6_t1_tid,
p6_t1_pid,
p6_t1_ptid,
"/good-exe",
"good-exe",
// Please note that the `deleted` will be removed.
"/usr/bin/bad-exe (deleted)");

ASSERT_EQ(get_field_as_string(evt, "proc.exepath"), "/usr/bin/bad-exe");
ASSERT_EQ(get_field_as_string(evt, "proc.name"), "good-exe");
Expand Down
13 changes: 12 additions & 1 deletion userspace/libsinsp/threadinfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -454,7 +454,7 @@ void sinsp_threadinfo::init(scap_threadinfo* pi) {
m_comm = pi->comm;
m_exe = pi->exe;
/* The exepath is extracted from `/proc/pid/exe`. */
m_exepath = pi->exepath;
set_exepath(std::string(pi->exepath));
m_exe_writable = pi->exe_writable;
m_exe_upper_layer = pi->exe_upper_layer;
m_exe_lower_layer = pi->exe_lower_layer;
Expand Down Expand Up @@ -1248,6 +1248,17 @@ void sinsp_threadinfo::update_main_fdtable() {
}
}

void sinsp_threadinfo::set_exepath(std::string&& exepath) {
constexpr char suffix[] = " (deleted)";
constexpr size_t suffix_len = sizeof(suffix) - 1; // Exclude null terminator

m_exepath = exepath;
if(m_exepath.size() > suffix_len &&
m_exepath.compare(m_exepath.size() - suffix_len, suffix_len, suffix) == 0) {
m_exepath.resize(m_exepath.size() - suffix_len);
}
}

static void fd_to_scap(scap_fdinfo* dst, sinsp_fdinfo* src) {
dst->type = src->m_type;
dst->ino = src->m_ino;
Expand Down
2 changes: 2 additions & 0 deletions userspace/libsinsp/threadinfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -634,6 +634,8 @@ class SINSP_PUBLIC sinsp_threadinfo : public libsinsp::state::table_entry {

void update_main_fdtable();

void set_exepath(std::string&& exepath);

private:
sinsp_threadinfo* get_cwd_root();
bool set_env_from_proc();
Expand Down
Loading