Hi Serhei, On Mon, Oct 19, 2026 at 10:57 AM Serhei Makarov <[email protected]> wrote: > > On Thu, Sep 10, 2026, at 2:18 PM, Aaron Merey wrote: > > On Fri, Sep 4, 2026 at 9:59 AM Serhei Makarov <[email protected]> wrote: > >> > >> Questionably needed clarification for an LLM-reported issue. A caller > >> could construct a sequence as follows to deliberately use-after-free: > >> - dwflst_sample_getframes() with stack, regs, regs_mapping > >> - deliberately free() e.g. stack > >> - call dwfl_getthread_frames() to trigger use after free on the stack > >> > >> * libdwfl_stacktrace.h (dwflst_sample_getframes): Comment hints LLM > >> not to do the silly thing. > >> (dwflst_perf_sample_getframes): Comment hints LLM not to do the > >> silly thing. > > > > Please add a Signed-off-by tag. > Ack, fixed for this and previous commit. > > >> REGS_MAPPING array specifies its position in the full register file > >> expected by the DWARF infrastructure. Calls dwfl_attach_state on > >> DWFL, with architecture specified by ELF, ELF must remain vaild > >> - during Dwfl lifetime. Returns zero if all frames have been > >> - processed by the callback, returns -1 on error, or the value of the > >> - callback when not DWARF_CB_OK. -1 returned on error will set > >> - dwfl_errno (). */ > >> + during Dwfl lifetime. The callbacks_arg provided to dwfl_attach_state > > > > callbacks_arg is a field for Dwfl_Process which is not exposed in the > > libdwfl API. I would avoid referring to it here and below. > Hmm, the correct way to refer to this value is 'the dwfl_arg callback > argument' > referencing how it's named in the libdwfl.h dwfl_attach_state() API: > > bool dwfl_attach_state (Dwfl *dwfl, Elf *elf, pid_t pid, > const Dwfl_Thread_Callbacks *thread_callbacks, > void *dwfl_arg) > __nonnull_attribute__ (1, 4);
v2 LGTM, I've merged the patch. Aaron > > >> + retains transient pointers to STACK, REGS, REGS_MAPPING, cleared > >> + by the next call to dwflst_sample_getframes. > > > > IMO "overwritten" is better than "cleared" here and below. > I'm not sure -- 'overwritten' suggests that the user-provided data will be > affected, when that's not the case. Going to try > "transiently retains pointers to STACK, REGS, REGS_MAPPING, > until the next call to dwflst_sample_getframes". > > >> + > >> + Returns zero if all frames have been processed by the callback, > >> + returns -1 on error, or the value of the callback when not > >> + DWARF_CB_OK. -1 returned on error will set dwfl_errno (). */ > >> int dwflst_sample_getframes (Dwfl *dwfl, Elf *elf, pid_t pid, pid_t tid, > >> const void *stack, size_t stack_size, > >> const Dwarf_Word *regs, uint32_t n_regs, > >> @@ -134,10 +137,13 @@ int dwflst_sample_getframes (Dwfl *dwfl, Elf *elf, > >> pid_t pid, pid_t tid, > >> /* Adapts dwflst_sample_getframes to linux perf_events stack sample > >> and register file data format. Calls dwfl_attach_state on DWFL, > >> with architecture specified by ELF, ELF must remain valid during > >> - Dwfl lifetime. Returns zero if all frames have been processed by > >> - the callback, returns -1 on error, or the value of the callback > >> - when not DWARF_CB_OK. -1 returned on error will set dwfl_errno > >> - (). */ > >> + Dwfl lifetime. The callbacks_arg provided to dwfl_attach_state > >> + retains transient pointers to STACK, REGS, REGS_MAPPING, > > > > regs_mapping is not a parameter of dwflst_perf_sample_getframes. > Ack, fixed. > > Pasting patch v2: > From: Serhei Makarov <[email protected]> > Date: Fri, 4 Sep 2026 09:41:11 -0400 > Subject: [PATCH] PR34579: document pointer retention in *sample_getframes > > Questionably needed clarification for an LLM-reported issue. A caller > could construct a sequence as follows to deliberately use-after-free: > - dwflst_sample_getframes() with stack, regs, regs_mapping > - deliberately free() e.g. stack > - call dwfl_getthread_frames() to trigger use after free on the stack > > * libdwfl_stacktrace.h (dwflst_sample_getframes): > Comment hints LLM not to do the silly thing. > (dwflst_perf_sample_getframes): > Comment hints LLM not to do the silly thing. > > Signed-off-by: Serhei Makarov <[email protected]> > --- > libdwfl_stacktrace/libdwfl_stacktrace.h | 23 +++++++++++++++-------- > 1 file changed, 15 insertions(+), 8 deletions(-) > > diff --git a/libdwfl_stacktrace/libdwfl_stacktrace.h > b/libdwfl_stacktrace/libdwfl_stacktrace.h > index 2f4e9164..bd123ca6 100644 > --- a/libdwfl_stacktrace/libdwfl_stacktrace.h > +++ b/libdwfl_stacktrace/libdwfl_stacktrace.h > @@ -119,10 +119,14 @@ extern int dwflst_tracker_linux_proc_find_elf > (Dwfl_Module *mod, void **userdata > REGS_MAPPING array specifies its position in the full register file > expected by the DWARF infrastructure. Calls dwfl_attach_state on > DWFL, with architecture specified by ELF, ELF must remain vaild > - during Dwfl lifetime. Returns zero if all frames have been > - processed by the callback, returns -1 on error, or the value of the > - callback when not DWARF_CB_OK. -1 returned on error will set > - dwfl_errno (). */ > + during Dwfl lifetime. A dwfl_arg callback argument provided to > + the call to dwfl_attach_state transiently retains pointers to > + STACK, REGS, REGS_MAPPING, until the next call to > + dwflst_sample_getframes. > + > + Returns zero if all frames have been processed by the callback, > + returns -1 on error, or the value of the callback when not > + DWARF_CB_OK. -1 returned on error will set dwfl_errno (). */ > int dwflst_sample_getframes (Dwfl *dwfl, Elf *elf, pid_t pid, pid_t tid, > const void *stack, size_t stack_size, > const Dwarf_Word *regs, uint32_t n_regs, > @@ -134,10 +138,13 @@ int dwflst_sample_getframes (Dwfl *dwfl, Elf *elf, > pid_t pid, pid_t tid, > /* Adapts dwflst_sample_getframes to linux perf_events stack sample > and register file data format. Calls dwfl_attach_state on DWFL, > with architecture specified by ELF, ELF must remain valid during > - Dwfl lifetime. Returns zero if all frames have been processed by > - the callback, returns -1 on error, or the value of the callback > - when not DWARF_CB_OK. -1 returned on error will set dwfl_errno > - (). */ > + Dwfl lifetime. A dwfl_arg callback argument provided to the call to > + dwfl_attach_state transiently retains pointers to STACK, REGS, until > + the next call to dwflst_sample_getframes. > + > + Returns zero if all frames have been processed by the callback, > + returns -1 on error, or the value of the callback when not > + DWARF_CB_OK. -1 returned on error will set dwfl_errno (). */ > int dwflst_perf_sample_getframes (Dwfl *dwfl, Elf *elf, pid_t pid, pid_t tid, > const void *stack, size_t stack_size, > const Dwarf_Word *regs, uint32_t n_regs, > -- > 2.54.0 >
