-
Notifications
You must be signed in to change notification settings - Fork 185
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
trace/dns + trace/exec + trace/open: fix unsafe typecasting #2443
Conversation
ce4dc5b
to
aed3175
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was trying another approach to avoid having to manually declare these structs: to copy the sample to a slice that is big enough, and then do the casting:
--- pkg/gadgets/trace/exec/tracer/tracer.go
+++ pkg/gadgets/trace/exec/tracer/tracer.go
@@ -148,9 +148,10 @@ func (t *Tracer) run() {
continue
}
- // this works regardless the kind of event because cwd is defined at the end of the
- // structure. (Just before args that are handled in a different way below)
- bpfEvent := (*execsnoopEvent)(unsafe.Pointer(&record.RawSample[0]))
+ var bpfEvent *execsnoopEvent
+ tmp := make([]byte, unsafe.Sizeof(*bpfEvent))
+ copy(tmp, record.RawSample)
+ bpfEvent = (*execsnoopEvent)(unsafe.Pointer(&tmp[0]))
event := types.Event{
Event: eventtypes.Event{
@@ -174,7 +175,7 @@ func (t *Tracer) run() {
args := &bpfEvent.Args
if t.config.GetCwd {
- bpfEventWithCwd := (*execsnoopWithCwdEvent)(unsafe.Pointer(&record.RawSample[0]))
+ bpfEventWithCwd := (*execsnoopWithCwdEvent)(unsafe.Pointer(&tmp[0]))
event.Cwd = gadgets.FromCString(bpfEventWithCwd.Cwd[:])
args = &bpfEventWithCwd.Args
}
It'll create this extra copy, but perhaps it's better than having to duplicate the structures? What do you think? (I'm fine with either change).
btw, trace open also has this issue:
inspektor-gadget/pkg/gadgets/trace/open/tracer/bpf/opensnoop.bpf.c
Lines 225 to 227 in e63af49
bpf_perf_event_output(ctx, &events, BPF_F_CURRENT_CPU, event, | |
sizeof(struct event) - | |
(PATH_MAX - full_fname_len)); |
I'm also fine with both solutions, however, as this is the hot path of the gadget, I lean a bit towards the faster solution with slightly higher maintenance cost (and since it's "legacy" anyway... hehe).
Ah, thanks. I'll add it once we've decided which solution to use. |
I agree, let's go for your solution. Only thing, would you mind adding a comment on the structure definition on the .bpf.c files indicating it has to be keep in sync as well? |
aed3175
to
ad322e8
Compare
Before this change, we cast incoming events from the RawSample byte slice directly to expected types (like in other gadgets). However, in these gadgets, we optimized the data we send in eBPF to reduce load by not sending empty fields. Casting those abbreviated events to the full struct though makes them not backed by memory anymore - and thus unsafe to use. This change adds a new type for each gadget containing only the guaranteed parts that are sent and fills the (dynamic) remainder directly from the RawSample data. In case of changes to the original event layout, these new structs have to be updated as well. Fixes #2337. Signed-off-by: Michael Friese <mfriese@microsoft.com>
ad322e8
to
d841b42
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM. Thanks for the fix!
Thanks for the reviews! |
Before this change, we cast incoming events from the RawSample byte slice directly to expected types (like in other gadgets). However, in these gadgets, we optimized the data we send in eBPF to reduce load by not sending empty fields. Casting those abbreviated events to the full struct though makes them not backed by memory anymore - and thus unsafe to use. This change adds a new type for each gadget containing only the guaranteed parts that are sent and fills the (dynamic) remainder directly from the RawSample data. In case of changes to the original event layout, these new structs have to be updated as well.
This also fixes an issue with the trace/dns example.
Fixes #2337.