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);
>> + 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