From: Arnaldo Carvalho de Melo <acme@kernel.org>
To: Alan Maguire <alan.maguire@oracle.com>
Cc: Jiri Olsa <jolsa@kernel.org>,
Clark Williams <williams@redhat.com>,
dwarves@vger.kernel.org, bpf@vger.kernel.org,
Andrii Nakryiko <andrii@kernel.org>,
Yonghong Song <yonghong.song@linux.dev>,
Arnaldo Carvalho de Melo <acme@redhat.com>
Subject: [PATCH 08/31] dwarf_loader: Allocate type_dcu via dwarf_cu__new to fix dangling stack pointer
Date: Wed, 29 Jul 2026 16:07:08 -0300 [thread overview]
Message-ID: <20260729190733.72876-9-acme@kernel.org> (raw)
In-Reply-To: <20260729190733.72876-1-acme@kernel.org>
From: Arnaldo Carvalho de Melo <acme@redhat.com>
In cus__load_module(), type_dcu was declared on the stack and passed
to __cus__load_debug_types(), which stores the pointer in type_cu->priv.
After cus__load_module() returns, type_cu->priv points to a dead stack
frame. When dwarf_cu__delete() later calls cu__free(cu, cu->priv), it
passes an invalid stack address to free(), causing heap corruption or a
crash.
Move the allocation into __cus__load_debug_types() using dwarf_cu__new(),
which allocates through cu__zalloc() — respecting the CU's obstack
setting so that the type_dcu lifetime is tied to the type_cu that owns
it and cleanup goes through the normal dwarf_cu__delete() path.
Fixes: 2938a70e1e2a73ff ("Add support for .debug_types sections.")
Reported-by: Sashiko:gemini-3-1-pro-preview # Running on a local machine
Assisted-by: Claude:claude-sonnet-4-5
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
dwarf_loader.c | 41 +++++++++++++++++++++++++----------------
1 file changed, 25 insertions(+), 16 deletions(-)
diff --git a/dwarf_loader.c b/dwarf_loader.c
index 14c90080f538e10d..b87519fa73405ff7 100644
--- a/dwarf_loader.c
+++ b/dwarf_loader.c
@@ -3889,7 +3889,7 @@ static int cu__set_common(struct cu *cu, struct conf_load *conf,
static int __cus__load_debug_types(struct cus *cus, struct conf_load *conf, Dwfl_Module *mod, Dwarf *dw, Elf *elf,
const char *filename, const unsigned char *build_id,
- int build_id_len, struct cu **cup, struct dwarf_cu *dcup)
+ int build_id_len, struct cu **cup, struct dwarf_cu **dcup)
{
Dwarf_Off off = 0, noff, type_off;
size_t cuhl;
@@ -3897,6 +3897,7 @@ static int __cus__load_debug_types(struct cus *cus, struct conf_load *conf, Dwfl
uint64_t signature;
*cup = NULL;
+ *dcup = NULL;
while (dwarf_next_unit(dw, off, &noff, &cuhl, NULL, NULL, &pointer_size,
&offset_size, &signature, &type_off)
@@ -3904,6 +3905,7 @@ static int __cus__load_debug_types(struct cus *cus, struct conf_load *conf, Dwfl
if (*cup == NULL) {
struct cu *cu;
+ struct dwarf_cu *dcu;
cu = cu__new("", pointer_size, build_id,
build_id_len, filename, conf->use_obstack);
@@ -3913,17 +3915,18 @@ static int __cus__load_debug_types(struct cus *cus, struct conf_load *conf, Dwfl
return DWARF_CB_ABORT;
}
- if (dwarf_cu__init(dcup, cu) != 0) {
+ dcu = dwarf_cu__new(cu);
+ if (dcu == NULL) {
cu__delete(cu);
return DWARF_CB_ABORT;
}
- dcup->cu = cu;
/* Funny hack. */
- dcup->type_unit = dcup;
- cu->priv = dcup;
+ dcu->type_unit = dcu;
+ cu->priv = dcu;
cu->dfops = &dwarf__ops;
*cup = cu;
+ *dcup = dcu;
cus__add(cus, cu);
}
@@ -4488,27 +4491,30 @@ static int cus__load_module(struct cus *cus, struct conf_load *conf,
int build_id_len = 0;
#endif
struct cu *type_cu;
- struct dwarf_cu type_dcu;
+ struct dwarf_cu *type_dcu;
int type_lsk = LSK__KEEPIT;
int lsk_worker_status = LSK__ABORT;
int res = __cus__load_debug_types(cus, conf, mod, dw, elf, filename, build_id, build_id_len, &type_cu, &type_dcu);
- if (res != 0) {
+ if (res != 0)
return res;
- }
if (type_cu != NULL) {
cu__finalize(type_cu, cus, conf);
- type_lsk = cus__steal_now(cus, type_cu, conf);
- if (type_lsk == LSK__DELETE) {
+ if (conf && conf->steal)
+ type_lsk = conf->steal(type_cu, conf);
+ /* Defer cu__delete() for LSK__DELETE until after main
+ * CUs are processed — they need type_dcu alive for
+ * DW_FORM_ref_sig8 resolution. Remove from the list
+ * now so the consumer doesn't see it twice. */
+ if (type_lsk == LSK__DELETE)
cus__remove(cus, type_cu);
- }
}
if (cus__merging_cu(dw, elf)) {
res = cus__merge_and_process_cu(cus, conf, mod, dw, elf, filename,
build_id, build_id_len,
- type_cu ? &type_dcu : NULL);
+ type_cu ? type_dcu : NULL);
} else {
struct dwarf_cus dcus = {
.off = 0,
@@ -4518,7 +4524,7 @@ static int cus__load_module(struct cus *cus, struct conf_load *conf,
.dw = dw,
.elf = elf,
.filename = filename,
- .type_dcu = type_cu ? &type_dcu : NULL,
+ .type_dcu = type_cu ? type_dcu : NULL,
.build_id = build_id,
.build_id_len = build_id_len,
.nr_cus_created = 0,
@@ -4527,12 +4533,15 @@ static int cus__load_module(struct cus *cus, struct conf_load *conf,
lsk_worker_status = dcus.lsk_status;
}
+ /* Deferred type CU cleanup: now that main CUs have finished
+ * resolving DW_FORM_ref_sig8 refs through type_dcu, it is
+ * safe to free the type CU. */
+ if (type_cu != NULL && type_lsk == LSK__DELETE)
+ cu__delete(type_cu);
+
if (res && lsk_worker_status == LSK__ABORT)
return res;
- if (type_lsk == LSK__DELETE)
- cu__delete(type_cu);
-
return DWARF_CB_OK;
}
--
2.55.0
next prev parent reply other threads:[~2026-07-29 19:07 UTC|newest]
Thread overview: 32+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-07-29 19:07 [PATCHES 00/31] pahole: Bug fixes and small improvements Arnaldo Carvalho de Melo
2026-07-29 19:07 ` [PATCH 01/31] cmake: Update minimum required version from 3.5 to 3.10 Arnaldo Carvalho de Melo
2026-07-29 19:07 ` [PATCH 02/31] Fix -Wsign-compare warnings across the codebase Arnaldo Carvalho de Melo
2026-07-29 19:07 ` [PATCH 03/31] btf_encoder: Fix interior pointer free and missing NULL check Arnaldo Carvalho de Melo
2026-07-29 19:07 ` [PATCH 04/31] dwarves: Fix missing list head initialization in type__clone_members Arnaldo Carvalho de Melo
2026-07-29 19:07 ` [PATCH 05/31] pahole: Fix instance memory leak on early returns in prototype__stdio_fprintf_value Arnaldo Carvalho de Melo
2026-07-29 19:07 ` [PATCH 06/31] ctf_loader, libctf: Fix error path resource leaks Arnaldo Carvalho de Melo
2026-07-29 19:07 ` [PATCH 07/31] dwarves: Don't search for holes before member byte sizes are cached Arnaldo Carvalho de Melo
2026-07-29 19:07 ` Arnaldo Carvalho de Melo [this message]
2026-07-29 19:07 ` [PATCH 09/31] dwarf_loader: Fix annotation failure leaks in variable and typedef creation Arnaldo Carvalho de Melo
2026-07-29 19:07 ` [PATCH 10/31] btf_encoder: Use btf_encoder__tag_type() for all type ID computations Arnaldo Carvalho de Melo
2026-07-29 19:07 ` [PATCH 11/31] pahole: Fix --errno typo that decrements instead of negating Arnaldo Carvalho de Melo
2026-07-29 19:07 ` [PATCH 12/31] dwarves: Fix heap buffer overflow in languages__parse realloc Arnaldo Carvalho de Melo
2026-07-29 19:07 ` [PATCH 13/31] btf_encoder: Fix early cleanup crashes in btf_encoder__new/delete Arnaldo Carvalho de Melo
2026-07-29 19:07 ` [PATCH 14/31] btf_encoder, libctf: Add elf_strptr NULL checks and fix kfunc bounds Arnaldo Carvalho de Melo
2026-07-29 19:07 ` [PATCH 15/31] dwarf_loader: Fix --fixup_silly_bitfields condition check Arnaldo Carvalho de Melo
2026-07-29 19:07 ` [PATCH 16/31] dwarf_loader: Skip libdw__lock when elfutils is built thread-safe Arnaldo Carvalho de Melo
2026-07-29 19:07 ` [PATCH 17/31] dwarf_loader: Fix data race in tag__init() decl_file string cache Arnaldo Carvalho de Melo
2026-07-29 19:07 ` [PATCH 18/31] pahole: Fix parse_btf_features("all") being a silent no-op Arnaldo Carvalho de Melo
2026-07-29 19:07 ` [PATCH 19/31] dwarves: Fix variable shadowing in __cus__find_struct_by_name() Arnaldo Carvalho de Melo
2026-07-29 19:07 ` [PATCH 20/31] dutil: Add exec_objcopy() shell-injection-safe helper Arnaldo Carvalho de Melo
2026-07-29 19:07 ` [PATCH 21/31] btf_encoder: Fall back to objcopy when llvm-objcopy is not available Arnaldo Carvalho de Melo
2026-07-29 19:07 ` [PATCH 22/31] dwarf_loader, btf_loader: Replace stale FIXME/XXX comments with explanations Arnaldo Carvalho de Melo
2026-07-29 19:07 ` [PATCH 23/31] pahole: Skip inline expansions during BTF encoding Arnaldo Carvalho de Melo
2026-07-29 19:07 ` [PATCH 24/31] pahole: Use fseek for seekable files in --prettify and --seek_bytes Arnaldo Carvalho de Melo
2026-07-29 19:07 ` [PATCH 25/31] pahole: Guard pipe_seek() against negative offsets Arnaldo Carvalho de Melo
2026-07-29 19:07 ` [PATCH 26/31] gobuffer: Remove 5 dead functions found via coverage analysis Arnaldo Carvalho de Melo
2026-07-29 19:07 ` [PATCH 27/31] dwarves: Remove 6 " Arnaldo Carvalho de Melo
2026-07-29 19:07 ` [PATCH 28/31] pfunct, dwarves_fprintf: Mark file-local functions as static Arnaldo Carvalho de Melo
2026-07-29 19:07 ` [PATCH 29/31] btf_encoder: Fix multi-dimensional array encoding Arnaldo Carvalho de Melo
2026-07-29 19:07 ` [PATCH 30/31] btf_loader: Fix multi-dimensional array loading Arnaldo Carvalho de Melo
2026-07-29 19:07 ` [PATCH 31/31] btfdiff: Remove --flat_arrays now that pahole encodes multi dim arrays in BTF Arnaldo Carvalho de Melo
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260729190733.72876-9-acme@kernel.org \
--to=acme@kernel.org \
--cc=acme@redhat.com \
--cc=alan.maguire@oracle.com \
--cc=andrii@kernel.org \
--cc=bpf@vger.kernel.org \
--cc=dwarves@vger.kernel.org \
--cc=jolsa@kernel.org \
--cc=williams@redhat.com \
--cc=yonghong.song@linux.dev \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox