8000 add bpf byte code capture by AsafEitani · Pull Request #2874 · aquasecurity/tracee · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

add bpf byte code capture #2874

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

Merged
merged 1 commit into from
Mar 21, 2023

Conversation

AsafEitani
Copy link
Contributor

fix #1274

1. Explain what the PR does

Adds BPF programs bytecode (JIT) capture.

2. Explain how to test it

tracee-ebpf -c bpf

@AsafEitani AsafEitani force-pushed the bpf_bytecode_capture branch 2 times, most recently from 92b1456 to 3e9541a Compare March 19, 2023 13:00
@AsafEitani AsafEitani force-pushed the bpf_bytecode_capture branch from 3e9541a to 078bab2 Compare March 19, 2023 14:07
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.

one last comment and we can merge

@AsafEitani AsafEitani force-pushed the bpf_bytecode_capture branch 4 times, most recently from 49807db to 1ee3493 Compare March 20, 2023 12:47
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

@rafaeldtinoco
Copy link
8000 Contributor
rafaeldtinoco commented Mar 21, 2023

Quick note, we pick also the libbpf nametest eBPF probe programs (from probe_kern_prog_name() libbpf internal function). So each capture will have the same eBPF object (probes) over and over. Not that this is a problem. Just wanted to highlight it.

# find . | grep test
./bpf.name-libbpf_nametest.pid-85426.59f4a931744dcdc62944a018ed3990e666ec6444616418d3b09a82dc5c753d52
./bpf.name-libbpf_nametest.pid-85339.59f4a931744dcdc62944a018ed3990e666ec6444616418d3b09a82dc5c753d52

Comment on lines 916 to 921
struct { /* anonymous struct used by BPF_PROG_LOAD command */
__u32 prog_type; /* one of enum bpf_prog_type */
__u32 insn_cnt;
__u64 insns;
__u64 license;
__u32 log_level; /* verbosity level of verifier */
__u32 log_size; /* size of user buffer */
__u64 log_buf; /* user supplied buffer */
__u32 kern_version; /* not used */
__u32 prog_flags;
char prog_name[BPF_OBJ_NAME_LEN];
__u32 prog_ifindex; /* ifindex of netdev to prep for */
/* For some prog types expected attach type must be known at
* load time to verify attach type specific parts of prog
* (context accesses, allowed helpers, etc).
*/
__u32 expected_attach_type;
__u32 prog_btf_fd; /* fd pointing to BTF type data */
__u32 func_info_rec_size; /* userspace bpf_func_info size */
__u64 func_info; /* func info */
__u32 func_info_cnt; /* number of bpf_func_info records */
__u32 line_info_rec_size; /* userspace bpf_line_info size */
__u64 line_info; /* line info */
__u32 line_info_cnt; /* number of bpf_line_info records */
__u32 attach_btf_id; /* in-kernel BTF type id to attach to */
union {
/* valid prog_fd to attach to bpf prog */
__u32 attach_prog_fd;
/* or valid module BTF object fd or 0 to attach to vmlinux */
__u32 attach_btf_obj_fd;
};
__u32 : 32; /* pad */
__u64 fd_array; /* array of FDs */
};

struct { /* anonymous struct for BPF_BTF_LOAD */
__u64 btf;
__u64 btf_log_buf;
__u32 btf_size;
__u32 btf_log_size;
__u32 btf_log_level;
};

Copy link
Contributor
@rafaeldtinoco rafaeldtinoco Mar 21, 2023

Choose a reason for hiding this comment

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

You have added the entire type here, not only the fields/members you're using, right? Isn't this type declared in /usr/include/linux/bpf.h for the "non-CO-RE" compilation? (it's a per kernel version "include" file and is compatible with non-CO-RE code, for sure).

If that wasn't the case, full missing types would go to either:

  • missing_definitions.h (CO-RE code)
  • missing_noncore_definitions.h (non CO-RE code)

But, in your case, the type exists for non CO-RE code so you only need to declare the fields/members you're REALLY using in the vmlinux.h file (not all the types).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Changed it - thanks for the catch. TBH I have little clue to what I'm doing regarding CORE and non CORE and I don't know how you divided it - I just try to make it work XD

Copy link
Contributor

Choose a reason for hiding this comment

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

No worries at all, we can help you find out where things go as long as it works as it did ;). Thanks, Asaf!

Copy link
Contributor

Choose a reason for hiding this comment

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

I would not call this file bpf.h. There are numerous bpf.h files, for kernel uapi (userland headers), internal files to the kernel, and libbpf bpf.h (multiple: userland and kernel). I would call something else IMHO.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

changed to bpf_prog.h

Copy link
Contributor
@rafaeldtinoco rafaeldtinoco left a comment

Choose a reason for hiding this comment

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

I'll finish the review tomorrow morning. I left some comments regarding documentation and minor stuff (headers placement, etc). Going through the rest of the code (more to get to know now, than anything else). Cheers!

@AsafEitani AsafEitani force-pushed the bpf_bytecode_capture branch 3 times, most recently from 6d8edd4 to 2359a8e Compare March 21, 2023 15:49

u32 insn_cnt = get_attr_insn_cnt(attr);
const struct bpf_insn *insns = get_attr_insns(attr);
unsigned int insn_size = (unsigned int) (sizeof(struct bpf_insn) * insn_cnt);
Copy link
Contributor
@rafaeldtinoco rafaeldtinoco Mar 21, 2023

Choose a reason for hiding this comment

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

@AsafEitani FTR only... you might already know that, just mentioning if not. We don't have a problem with using sizeof(struct bpf_insn) here because the struct bpf_insn won't ever have its size changed.

But, whenever you want to get its size, the correct approach for any other kernel types is to use the bpf type helper bpf_core_type_size(type) for CO-RE and sizeof() for NON-CO-RE.

This is major because the type might change from one kernel to another and for portability, the helper will consider that (So you don't need to declare the FULL type in the vmlinux.h file, only the types you really use).

Copy link
Contributor
@rafaeldtinoco rafaeldtinoco left a comment

Choose a reason for hiding this comment

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

LGTM

@rafaeldtinoco rafaeldtinoco merged commit eb6076b into aquasecurity:main Mar 21, 2023
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.

BPF program capturing
4 participants
0