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

Add dynamic extraction of a parameter attribute #3143

Open
wants to merge 15 commits into
base: main
Choose a base branch
from
Open
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
29 changes: 29 additions & 0 deletions bpf/process/generic_calls.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,11 +62,23 @@ generic_start_process_filter(void *ctx, struct bpf_map_def *calls)
return 0;
}

FUNC_INLINE int
extract_arg_depth(u32 i, struct extract_arg_data *data)
{
if (i >= MAX_BTF_ARG_DEPTH || !data->btf_config[i].is_initialized)
return 1;
*data->arg = *data->arg + data->btf_config[i].offset;
if (data->btf_config[i].is_pointer)
probe_read((void *)data->arg, sizeof(char *), (void *)*data->arg);
return 0;
}

FUNC_INLINE int
generic_process_event(void *ctx, struct bpf_map_def *tailcals)
{
struct msg_generic_kprobe *e;
struct event_config *config;
struct config_btf_arg *btf_config;
int index, zero = 0;
unsigned long a;
long ty, total;
Expand All @@ -87,6 +99,23 @@ generic_process_event(void *ctx, struct bpf_map_def *tailcals)
a = (&e->a0)[index];
total = e->common.size;

btf_config = (&config->btf_arg0)[index];
if (index <= 4 && btf_config[0].is_initialized) {
struct extract_arg_data extract_data = {
.btf_config = btf_config,
.arg = &a,
};
#ifndef __V61_BPF_PROG
#pragma unroll
for (int i = 0; i < MAX_BTF_ARG_DEPTH; ++i) {
if (extract_arg_depth(i, &extract_data))
break;
}
#else
loop(MAX_BTF_ARG_DEPTH, extract_arg_depth, &extract_data, 0);
#endif /* __V61_BPF_PROG */
}

/* Read out args1-5 */
ty = (&config->arg0)[index];
if (total < MAX_TOTAL) {
Expand Down
18 changes: 18 additions & 0 deletions bpf/process/types/basic.h
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,19 @@ struct selector_arg_filters {
__u32 argoff[5];
} __attribute__((packed));

struct config_btf_arg {
__u32 offset;
__u16 is_pointer;
__u16 is_initialized;
} __attribute__((packed));

struct extract_arg_data {
struct config_btf_arg *btf_config;
unsigned long *arg;
};

#define MAX_BTF_ARG_DEPTH 10

struct event_config {
__u32 func_id;
__s32 arg0;
Expand Down Expand Up @@ -172,6 +185,11 @@ struct event_config {
*/
__u32 policy_id;
__u32 flags;
struct config_btf_arg btf_arg0[MAX_BTF_ARG_DEPTH];
struct config_btf_arg btf_arg1[MAX_BTF_ARG_DEPTH];
struct config_btf_arg btf_arg2[MAX_BTF_ARG_DEPTH];
struct config_btf_arg btf_arg3[MAX_BTF_ARG_DEPTH];
struct config_btf_arg btf_arg4[MAX_BTF_ARG_DEPTH];
} __attribute__((packed));

#define MAX_ARGS_SIZE 80
Expand Down
55 changes: 55 additions & 0 deletions docs/content/en/docs/concepts/tracing-policy/hooks.md
Original file line number Diff line number Diff line change
Expand Up @@ -400,6 +400,61 @@ The `maxData` flag does not work with `returnCopy` flag at the moment, so it's
usable only for syscalls/functions that do not require return probe to read the
data.

### Advanced usage

For specific use cases, you may want to extract a specific attribute from the argument.
For instance you have `struct linux_binprm` as first argument and want to filter parent
process name, you can do it as following.

```yaml
apiVersion: cilium.io/v1alpha1
kind: TracingPolicy
metadata:
name: "lsm"
spec:
lsmhooks:
- hook: "bprm_check_security"
args:
- index: 0
type: "linux_binprm"
extractParam: "mm.owner.real_parent.comm"
overwriteType: "string"
selectors:
- matchActions:
- action: Post
```

The above policy will display the parent process name every time the hook is called.
The `extractParam` field is used to reach a specific data into the `struct
linux_binprm`. It is important to set `overwriteType` as well to make sure the
reached data is read correctly (as a string in this case).

{{< caution >}}
- This feature requires you to know exactly what you are looking for in the attributes
of the hook parameters. For instance, if you want to have a look on what is
available inside `struct linux_binprm`, take a look at the
[Bootlin website](https://elixir.bootlin.com/linux/v6.12.5/source/include/linux/binfmts.h#L18)

- Some structures are dynamic. This means that they may change at runtime. So you need to
be aware of what you are looking for.
{{< /caution >}}

Tetragon can also handle some structures such as `struct file` or `struct
path` and few others. This means you can also extract the whole struct, if it is
available in the attributes of the parameter, and set the type with the correct type
like this :

```yaml
- index: 0
type: "linux_binprm"
extractParam: "file"
overwriteType: "file"
# Or
# extractParam: "file.f_path"
# overwriteType: "path"
```


## Return values

A `TracingPolicy` spec can specify that the return value should be reported in
Expand Down
15 changes: 15 additions & 0 deletions examples/tracingpolicy/lsm_track_grandparent.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
apiVersion: cilium.io/v1alpha1
kind: TracingPolicy
metadata:
name: "lsm"
spec:
lsmhooks:
- hook: "bprm_check_security"
args:
- index: 0
type: "linux_binprm"
extractParam: "mm.owner.real_parent.real_parent.comm"
overwriteType: "string"
selectors:
- matchActions:
- action: Post
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,10 @@ spec:
trace output.
items:
properties:
extractParam:
default: ""
description: Extract Specific subargument in structure
type: string
index:
description: Position of the argument.
format: int32
Expand All @@ -139,6 +143,11 @@ spec:
will fetch at most 4096 bytes. In later kernels (>=5.4) tetragon
supports fetching up to 327360 bytes if this flag is turned on
type: boolean
overwriteType:
default: ""
description: Overwrite the Type argument. Use it only
with extraParam
type: string
returnCopy:
default: false
description: |-
Expand Down Expand Up @@ -221,6 +230,10 @@ spec:
returnArg:
description: A return argument to include in the trace output.
properties:
extractParam:
default: ""
description: Extract Specific subargument in structure
type: string
index:
description: Position of the argument.
format: int32
Expand All @@ -237,6 +250,11 @@ spec:
will fetch at most 4096 bytes. In later kernels (>=5.4) tetragon
supports fetching up to 327360 bytes if this flag is turned on
type: boolean
overwriteType:
default: ""
description: Overwrite the Type argument. Use it only with
extraParam
type: string
returnCopy:
default: false
description: |-
Expand Down Expand Up @@ -834,6 +852,10 @@ spec:
trace output.
items:
properties:
extractParam:
default: ""
description: Extract Specific subargument in structure
type: string
index:
description: Position of the argument.
format: int32
Expand All @@ -850,6 +872,11 @@ spec:
will fetch at most 4096 bytes. In later kernels (>=5.4) tetragon
supports fetching up to 327360 bytes if this flag is turned on
type: boolean
overwriteType:
default: ""
description: Overwrite the Type argument. Use it only
with extraParam
type: string
returnCopy:
default: false
description: |-
Expand Down Expand Up @@ -1484,6 +1511,10 @@ spec:
trace output.
items:
properties:
extractParam:
default: ""
description: Extract Specific subargument in structure
type: string
index:
description: Position of the argument.
format: int32
Expand All @@ -1500,6 +1531,11 @@ spec:
will fetch at most 4096 bytes. In later kernels (>=5.4) tetragon
supports fetching up to 327360 bytes if this flag is turned on
type: boolean
overwriteType:
default: ""
description: Overwrite the Type argument. Use it only
with extraParam
type: string
returnCopy:
default: false
description: |-
Expand Down Expand Up @@ -2069,6 +2105,10 @@ spec:
trace output.
items:
properties:
extractParam:
default: ""
description: Extract Specific subargument in structure
type: string
index:
description: Position of the argument.
format: int32
Expand All @@ -2085,6 +2125,11 @@ spec:
will fetch at most 4096 bytes. In later kernels (>=5.4) tetragon
supports fetching up to 327360 bytes if this flag is turned on
type: boolean
overwriteType:
default: ""
description: Overwrite the Type argument. Use it only
with extraParam
type: string
returnCopy:
default: false
description: |-
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,10 @@ spec:
trace output.
items:
properties:
extractParam:
default: ""
description: Extract Specific subargument in structure
type: string
index:
description: Position of the argument.
format: int32
Expand All @@ -139,6 +143,11 @@ spec:
will fetch at most 4096 bytes. In later kernels (>=5.4) tetragon
supports fetching up to 327360 bytes if this flag is turned on
type: boolean
overwriteType:
default: ""
description: Overwrite the Type argument. Use it only
with extraParam
type: string
returnCopy:
default: false
description: |-
Expand Down Expand Up @@ -221,6 +230,10 @@ spec:
returnArg:
description: A return argument to include in the trace output.
properties:
extractParam:
default: ""
description: Extract Specific subargument in structure
type: string
index:
description: Position of the argument.
format: int32
Expand All @@ -237,6 +250,11 @@ spec:
will fetch at most 4096 bytes. In later kernels (>=5.4) tetragon
supports fetching up to 327360 bytes if this flag is turned on
type: boolean
overwriteType:
default: ""
description: Overwrite the Type argument. Use it only with
extraParam
type: string
returnCopy:
default: false
description: |-
Expand Down Expand Up @@ -834,6 +852,10 @@ spec:
trace output.
items:
properties:
extractParam:
default: ""
description: Extract Specific subargument in structure
type: string
index:
description: Position of the argument.
format: int32
Expand All @@ -850,6 +872,11 @@ spec:
will fetch at most 4096 bytes. In later kernels (>=5.4) tetragon
supports fetching up to 327360 bytes if this flag is turned on
type: boolean
overwriteType:
default: ""
description: Overwrite the Type argument. Use it only
with extraParam
type: string
returnCopy:
default: false
description: |-
Expand Down Expand Up @@ -1484,6 +1511,10 @@ spec:
trace output.
items:
properties:
extractParam:
default: ""
description: Extract Specific subargument in structure
type: string
index:
description: Position of the argument.
format: int32
Expand All @@ -1500,6 +1531,11 @@ spec:
will fetch at most 4096 bytes. In later kernels (>=5.4) tetragon
supports fetching up to 327360 bytes if this flag is turned on
type: boolean
overwriteType:
default: ""
description: Overwrite the Type argument. Use it only
with extraParam
type: string
returnCopy:
default: false
description: |-
Expand Down Expand Up @@ -2069,6 +2105,10 @@ spec:
trace output.
items:
properties:
extractParam:
default: ""
description: Extract Specific subargument in structure
type: string
index:
description: Position of the argument.
format: int32
Expand All @@ -2085,6 +2125,11 @@ spec:
will fetch at most 4096 bytes. In later kernels (>=5.4) tetragon
supports fetching up to 327360 bytes if this flag is turned on
type: boolean
overwriteType:
default: ""
description: Overwrite the Type argument. Use it only
with extraParam
type: string
returnCopy:
default: false
description: |-
Expand Down
Loading
Loading