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

child.cpp: validate_cmd: Support symbolic links in environment variables #2708

Merged
merged 2 commits into from
Aug 16, 2023

Conversation

Rtoax
Copy link
Contributor

@Rtoax Rtoax commented Aug 3, 2023

On some systems /bin is a symbolic link to /usr/bin (/bin -> /usr/bin), When using the '-c' parameter to specify the executable program in the environment variable, the problem of "multiple binary files matching" occurs, for example:

  $ sudo bpftrace -e 'kprobe:do_nanosleep { printf("%d sleeping\n", pid); }' -c 'sleep 5'
  ERROR: Failed to fork child: path 'sleep' must refer to a unique binary but matched 2 binaries

Debugging the bpftrace program through gdb can also be verified:

  (gdb) p valid_executable_paths
  $9 = std::vector of length 2, capacity 2 = {"/bin/ls", "/usr/bin/ls"}

This commit fixes the issue. The v1[0] will cause CICD busybox error.

[0] #2689

@Rtoax
Copy link
Contributor Author

Rtoax commented Aug 3, 2023

@danobi Seems all is well. please review. thanks.

src/child.cpp Outdated Show resolved Hide resolved
@Rtoax Rtoax force-pushed the patch-46-Fix-resolve_binary_path-v3 branch from 8f2d0d8 to 71533ac Compare August 3, 2023 07:46
@viktormalik
Copy link
Contributor

Can we create a test for this?

@Rtoax
Copy link
Contributor Author

Rtoax commented Aug 3, 2023

Can we create a test for this?

Is this necessary? This PR only solves the error when /usr/bin/sleep and /bin/sleep are the same executable file. How should this situation be deployed in the CICD environment?

$ ls -l /bin
lrwxrwxrwx. 1 root root 7 Aug 10  2021 /bin -> usr/bin
$ realpath /bin/sleep
/usr/bin/sleep

This problem may not exist in different environments (including CICD), so I suggest not to add a test case. What do you think?

@viktormalik Or we can create a /usr/sbin/sleep symbolic link to /usr/bin/sleep, like:

TEST(childproc, multi_exe_link_match)
{
   // Create /usr/sbin/sleep -> /usr/bin/sleep
   // Test bpftrace -e '...' sleep 5
}

However, i still think it's not necessary to add this test case.

@Rtoax Rtoax requested a review from viktormalik August 3, 2023 08:41
@Rtoax Rtoax force-pushed the patch-46-Fix-resolve_binary_path-v3 branch from 71533ac to e79ff58 Compare August 3, 2023 12:37
@Rtoax
Copy link
Contributor Author

Rtoax commented Aug 3, 2023

I just force push a modification. There may be worse cases like

  $ realpath /usr/bin/ping /bin/ping /usr/sbin/ping /sbin/ping
  /usr/bin/ping
  /usr/bin/ping
  /usr/bin/ping
  /usr/bin/ping

  $ sudo bpftrace -e 'kprobe:do_nanosleep { printf("%d sleeping\n", pid); }' -c 'ping -c 4 0'
  ERROR: Failed to fork child: path 'ping' must refer to a unique binary but matched 4 binaries

So instead of using case 2 to solve it, it is better to use std::unordered_set<std::string>+abs_path() to solve this problem.

On some systems /bin is a symbolic link to /usr/bin (/bin -> /usr/bin), When
using the '-c' parameter to specify the executable program in the environment
variable, the problem of "multiple binary files matching" occurs, for example:

  $ sudo bpftrace -e 'kprobe:do_nanosleep { printf("%d sleeping\n", pid); }' -c 'sleep 5'
  ERROR: Failed to fork child: path 'sleep' must refer to a unique binary but matched 2 binaries

Debugging the bpftrace program through gdb can also be verified:

  (gdb) p valid_executable_paths
  $9 = std::vector of length 2, capacity 2 = {"/bin/ls", "/usr/bin/ls"}

Another situation is:

  $ realpath /usr/bin/ping /bin/ping /usr/sbin/ping /sbin/ping
  /usr/bin/ping
  /usr/bin/ping
  /usr/bin/ping
  /usr/bin/ping

  $ sudo bpftrace -e 'kprobe:do_nanosleep { printf("%d sleeping\n", pid); }' -c 'ping -c 4 0'
  ERROR: Failed to fork child: path 'ping' must refer to a unique binary but matched 4 binaries

This commit fixes this problem. See also v1[0], v2[1].

[0] bpftrace#2682
[1] bpftrace#2689

Signed-off-by: Rong Tao <[email protected]>
@Rtoax Rtoax force-pushed the patch-46-Fix-resolve_binary_path-v3 branch from e79ff58 to e24713e Compare August 3, 2023 12:41
@danobi
Copy link
Member

danobi commented Aug 4, 2023

The fix looks good to me. But I agree with Viktor -- test here would be good. But rather than depend on CI environment (which is not reliable like you mention), we could create a tempdir and then populate it with a an executable shell script and some symlinks to it. I think that should be reliable.

@Rtoax
Copy link
Contributor Author

Rtoax commented Aug 5, 2023

The fix looks good to me. But I agree with Viktor -- test here would be good. But rather than depend on CI environment (which is not reliable like you mention), we could create a tempdir and then populate it with a an executable shell script and some symlinks to it. I think that should be reliable.

I have a question, shall we add a test example in C, such as the following code in tests/child.cpp:

TEST(childproc, match_multi_exe)
{
  char path[] = "rootfs/";
  // make temp rootfs directory
  // make /usr/bin/ under rootfs
  // create tmp shell script "sleep.sh" (with x permission)
  // create link: /bin -> /usr/bin
  // put the rootfs/usr/bin and rootfs/bin to env
  // THEN, test sleep.sh
}

right? I'm not sure if my idea is accurate, if not, please give me some advice. thanks.

@danobi
Copy link
Member

danobi commented Aug 10, 2023

Yeah that looks right to me

@Rtoax
Copy link
Contributor Author

Rtoax commented Aug 11, 2023

Yeah that looks right to me

OK, I'll try it.

@Rtoax
Copy link
Contributor Author

Rtoax commented Aug 14, 2023

@danobi @viktormalik I just add test childproc.multi_exec_match, please review.

        $ sudo ./tests/bpftrace_test --gtest_filter=childproc.multi_exec_match
        Note: Google Test filter = childproc.multi_exec_match
        [==========] Running 1 test from 1 test suite.
        [----------] Global test environment set-up.
        [----------] 1 test from childproc
        [ RUN      ] childproc.multi_exec_match
        [       OK ] childproc.multi_exec_match (10 ms)
        [----------] 1 test from childproc (10 ms total)
    
        [----------] Global test environment tear-down
        [==========] 1 test from 1 test suite ran. (10 ms total)
        [  PASSED  ] 1 test.

@Rtoax Rtoax force-pushed the patch-46-Fix-resolve_binary_path-v3 branch 2 times, most recently from 8615546 to 3145b82 Compare August 14, 2023 04:52
src/child.cpp Outdated Show resolved Hide resolved
src/child.cpp Outdated Show resolved Hide resolved
src/utils.h Outdated Show resolved Hide resolved
tests/child.cpp Outdated Show resolved Hide resolved
tests/child.cpp Outdated Show resolved Hide resolved
tests/child.cpp Outdated Show resolved Hide resolved
@Rtoax Rtoax force-pushed the patch-46-Fix-resolve_binary_path-v3 branch from 3145b82 to 5d46e6f Compare August 16, 2023 00:48
    $ sudo ./tests/bpftrace_test --gtest_filter=childproc.multi_exec_match
    Note: Google Test filter = childproc.multi_exec_match
    [==========] Running 1 test from 1 test suite.
    [----------] Global test environment set-up.
    [----------] 1 test from childproc
    [ RUN      ] childproc.multi_exec_match
    [       OK ] childproc.multi_exec_match (10 ms)
    [----------] 1 test from childproc (10 ms total)

    [----------] Global test environment tear-down
    [==========] 1 test from 1 test suite ran. (10 ms total)
    [  PASSED  ] 1 test.

Signed-off-by: Rong Tao <[email protected]>
@Rtoax Rtoax force-pushed the patch-46-Fix-resolve_binary_path-v3 branch from 5d46e6f to dad5a49 Compare August 16, 2023 01:13
@Rtoax Rtoax requested a review from danobi August 16, 2023 02:10
Copy link
Member

@danobi danobi left a comment

Choose a reason for hiding this comment

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

thanks for iterating on this!

@danobi danobi merged commit f659c1c into bpftrace:master Aug 16, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants