tetragon: add support to preload user strings#4489
Conversation
c385182 to
4960b3b
Compare
35fd2f0 to
76dbe12
Compare
✅ Deploy Preview for tetragon ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
Adding test that loads string pointer to register and will be used in following tests. Signed-off-by: Jiri Olsa <jolsa@kernel.org>
76dbe12 to
e1cd620
Compare
| struct { | ||
| __uint(type, BPF_MAP_TYPE_PERCPU_ARRAY); | ||
| __uint(max_entries, 1); | ||
| __type(key, __u32); | ||
| __type(value, struct preload_data); | ||
| } sleepable_preload_heap SEC(".maps"); |
There was a problem hiding this comment.
I don't see that this is used anywhere. I do see that process_call_heap was used.
There was a problem hiding this comment.
nah I messed up the setup.. copy paste error, thanks
|
|
||
| data = map_lookup_elem(&process_call_heap, &zero); | ||
| if (!data) | ||
| return 0; | ||
|
|
||
| bpf_copy_from_user_str(data, sizeof(*data), (const void *)val, 0); | ||
| map_update_elem(&sleepable_preload, &id, data, BPF_ANY); |
There was a problem hiding this comment.
I think that this is prone to a race. If after line 49, the context is preempted due to the fact that we called bpf_copy_from_user* (which can trigger a page fault) another context can overwrite what's stored in data before line 50 is executed.
I'm not sure if we can safely use BPF_MAP_TYPE_PERCPU_ARRAY for a heap in this case.
There was a problem hiding this comment.
yes, you're right.. I switched to using just the hash based per process/thread, thanks
|
I think that it would be helpful to explicitly call out the motivation here. I think we are doing this in order to be able to page in userspace memory for the cases where we would encounter a page fault in order to access memory. As this problem is a common for reading strings, they are the first type wired to use this. Is this an accurate understanding, or am I missing the point? |
|
Why is this for x86_64 only? Recently, I've been experimenting with reading string args. From my limited testing, I saw that page faults only happened on x86_64. (It didn't seem to happen on arm64). Will arm64 ever need this functionality? |
|
This PR is specific to data source pt_regs. I think it would be nice to extend similar logic for string arg reading as well. Recently, I experimented with trying to read string arguments from uprobes using the What do you think about me trying to extend this in that way? |
Adding uprobe preload program to allow loading data in sleepable context. The preload program is executed before the main program loads the data and passes it via map to main program. So far we allow only string type data to be preloaded. Signed-off-by: Jiri Olsa <jolsa@kernel.org>
Adding support to attach uprobe preload program. It's attached to be executed before the main program. We also attach cleanup program that removes preloaded data from the map after the main program is executed. The preload program depends on bpf_copy_from_user_str kfunc and x86 arch. Signed-off-by: Jiri Olsa <jolsa@kernel.org>
Adding uprobe preload test that loads user space string and ensures it's loaded. Signed-off-by: Jiri Olsa <jolsa@kernel.org>
396a9a9 to
fc4a53c
Compare
I tried to describe that in the PR description.. so ATM we need to delegate reading from user space to sleepable program, because now we can't make the main generic sensor sleepable ... there's pending kernel change for that, so we might be able to do that in the future, but so far we need the preload bit |
I'm not sure about arm, that's why I made it x86 specific, because it's problem in there AFAIK.. if you think it's needed for arm as well, it should be easy to switch on |
sure, I added just string so far but I think we will need other types soon as I said earlier there's pending kernel change that will allow uprobe sensor to be sleepable, but we will still need preload for old kernels ... and we should somehow make those 2 approaches co-exists together |
I'm trying to confirm the motivation for making reading from user space sleepable. I think it's so we can access any memory within the user space program. Otherwise, we would not be able to access memory that hasn't been paged in before the uprobe hook point. Is this the motivation? |
yep, exactly |
this recap would have been awesome from the start to understand the motivation directly 😅 |
Adding uprobe preload program to allow loading data in sleepable context. The preload program is executed before the main program loads the data and passes it via map to main program.
So far we allow only string type data to be preloaded.