Re: [PATCH] tracing: fix memcpy size when copying stack entries

From: Sven Schnelle
Date: Wed Jul 12 2023 - 10:32:20 EST


Hi Steven,

Steven Rostedt <rostedt@xxxxxxxxxxx> writes:

>> As I don't know how the fortifier works, nor what exactly it is checking,
>> do you have any idea on how to quiet it?
>>
>> This is a false positive, as I described before.
>
>
> Hmm, maybe this would work?
>
> diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c
> index 4529e264cb86..20122eeccf97 100644
> --- a/kernel/trace/trace.c
> +++ b/kernel/trace/trace.c
> @@ -3118,6 +3118,7 @@ static void __ftrace_trace_stack(struct trace_buffer *buffer,
> struct ftrace_stack *fstack;
> struct stack_entry *entry;
> int stackidx;
> + void *ptr;
>
> /*
> * Add one, for this function and the call to save_stack_trace()
> @@ -3161,9 +3162,25 @@ static void __ftrace_trace_stack(struct trace_buffer *buffer,
> trace_ctx);
> if (!event)
> goto out;
> - entry = ring_buffer_event_data(event);
> + ptr = ring_buffer_event_data(event);
> + entry = ptr;
> +
> + /*
> + * For backward compatibility reasons, the entry->caller is an
> + * array of 8 slots to store the stack. This is also exported
> + * to user space. The amount allocated on the ring buffer actually
> + * holds enough for the stack specified by nr_entries. This will
> + * go into the location of entry->caller. Due to string fortifiers
> + * checking the size of the destination of memcpy() it triggers
> + * when it detects that size is greater than 8. To hide this from
> + * the fortifiers, we use "ptr" and pointer arithmetic to assign caller.
> + *
> + * The below is really just:
> + * memcpy(&entry->caller, fstack->calls, size);
> + */
> + ptr += offsetof(typeof(*entry), caller);
> + memcpy(ptr, fstack->calls, size);
>
> - memcpy(&entry->caller, fstack->calls, size);
> entry->size = nr_entries;
>
> if (!call_filter_check_discard(call, entry, buffer, event))
>
>

I just sent about the same thing without the nice comment. So yes, this
works. :-)