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

fix empty arguments resolution #4442

Merged
merged 2 commits into from
Jan 15, 2025
Merged

Conversation

ShohamBit
Copy link
Collaborator

@ShohamBit ShohamBit commented Dec 18, 2024

1. Explain what the PR does

make check-pr:

1cbdc3d tests: add argument parsers tests
69d55cb fix: empty arguments resolution

69d55cb fix: empty arguments resolution

When tracee tries to resolve a numeric argument to a string (e.g. cmd value of
bpf syscall), if the resolution fails, the event field will contain an empty
string.

Return the raw value as a string in case of a failed resolution.

2. Explain how to test it

In order to test you can run the test in the file with this command

GOOS=linux CC=clang GOARCH=amd64 CGO_CFLAGS="-I/tracee/dist/libbpf -I/tracee/3rdparty/libbpf/include/uapi" CGO_LDFLAGS="-L/tracee/dist/libbpf/obj -lbpf" \
go test \
	-tags ebpf \
        -v \
        -short \
	-race \
	-coverprofile=coverage.txt \
	./pkg/events -run TestParseArgsHelpers
  • this will run the test functions for parse_args_helpers.go file
  • you can change TestParseArgsHelpers to a function name like: TestParseBPFCmd to test a more specific

3. Other comments

Resolves #3892

@yanivagman
Copy link
Collaborator

Let's change all parsers inside this file that currently return an empty value on an error to return the raw value instead

@ShohamBit
Copy link
Collaborator Author

Let's change all parsers inside this file that currently return an empty value on an error to return the raw value instead.

Okay, but I think the code is still going to look weird because if we just print the information without any need for processing it behind the scenes, why would we write the function like this:

func funcArg(arg *trace.Argument, val uint64) {
    arg.Type = "string"
    argument, err := parsers.funcArg(mode) 
    if err != nil {
        arg.Value = "" 
        return 
    }
    arg.Value = argument.String() 
}

instead of like this:

func funcArg(arg *tracee.Argument, val uint64) {
    arg.Type = "string"
    arg.Value = val 
}

or just remove it entirely?

It looks pretty weird that we check for an error and don't even use it.

Note: Not every function behaves like this, but most of them do.

@oshaked1
Copy link
Contributor

It looks pretty weird that we check for an error and don't even use it.

We do use the error, that way we know to use the raw value.

@yanivagman
Copy link
Collaborator

Let's change all parsers inside this file that currently return an empty value on an error to return the raw value instead.

Okay, but I think the code is still going to look weird because if we just print the information without any need for processing it behind the scenes, why would we write the function like this:

func funcArg(arg *trace.Argument, val uint64) {
    arg.Type = "string"
    argument, err := parsers.funcArg(mode) 
    if err != nil {
        arg.Value = "" 
        return 
    }
    arg.Value = argument.String() 
}

instead of like this:

func funcArg(arg *tracee.Argument, val uint64) {
    arg.Type = "string"
    arg.Value = val 
}

or just remove it entirely?

It looks pretty weird that we check for an error and don't even use it.

Note: Not every function behaves like this, but most of them do.

Because the parsers return the parsed value of the argument. For example, if some (fake) argument has a raw value 0x4 which means F_WRITE, the output string will be "F_WRITE". However, if it has a value of 0x20, but the parsers don't know this value, an error will be returned. In this case, we can simply return the string value of the raw argument, which is "0x20"

@ShohamBit ShohamBit changed the title fix issue 3892 fix empty arguments resolution Dec 22, 2024
@oshaked1
Copy link
Contributor

oshaked1 commented Jan 1, 2025

LGTM

@ShohamBit
Copy link
Collaborator Author

@yanivagman I added tests for parse_args_helpers.go

Copy link
Member

@geyslan geyslan left a comment

Choose a reason for hiding this comment

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

Put some thoughts.

docs/man/scope.1 Outdated Show resolved Hide resolved
pkg/events/parse_args_helpers.go Outdated Show resolved Hide resolved
pkg/events/parsers/data_parsers.go Outdated Show resolved Hide resolved
When tracee tries to resolve a numeric argument to a string (e.g. cmd value of
bpf syscall), if the resolution fails, the event field will contain an empty
string.

Return the raw value as a string in case of a failed resolution.
@ShohamBit ShohamBit force-pushed the issue_3892 branch 2 times, most recently from 1cbdc3d to a3c9df7 Compare January 8, 2025 14:29
@@ -157,7 +160,7 @@ func parseBPFCmd(arg *trace.Argument, cmd uint64) {
arg.Type = "string"
bpfCommandArgument, err := parsers.ParseBPFCmd(cmd)
if err != nil {
arg.Value = ""
arg.Value = strconv.FormatUint(cmd, 10)
Copy link
Collaborator

Choose a reason for hiding this comment

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

@ShohamBit

Since the cmd field from both ebpf and security_bpf is int, shouldn't we use the following instead?

arg.Value = strconv.FormatInt(int64(cmd), 10)

If we use BPF_INVALID_CMD=-1 in the python script, the Tracee result in cmd field is 18446744073709551615 (0xFFFFFFFFFFFFFFFF) and not -1, take a look:

sudo ./dist/tracee -e bpf -s comm=python3.10
TIME             UID    COMM             PID     TID     RET              EVENT                     ARGS
06:13:50:764876  1000   python3.10       117825  117825  -1               bpf                       cmd: 18446744073709551615, attr: 0x0, size: 0

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

well as you can see the cmd arg is unit64 and not int64, do you suggest we change it to int64?

Copy link
Collaborator

Choose a reason for hiding this comment

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

I was discussing it with @geyslan and decided to open this issue #4504. Realized that there are some casting between int and uint that should be avoid (at least from my understanding).

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I reviewed this issue and think it is a great addition, also removes unnecessary casting that will also resolute in better performance

Copy link
Collaborator

@yanivagman yanivagman left a comment

Choose a reason for hiding this comment

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

LGTM

@yanivagman yanivagman merged commit 2c33665 into aquasecurity:main Jan 15, 2025
38 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Failure in argument name resolution results in empty value
5 participants