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
>

Reply via email to