From nobody Mon Jul 6 01:06:17 2026 X-Original-To: dev-commits-src-all@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4gtmQL17bSz6k7SN for ; Mon, 06 Jul 2026 01:06:18 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "YR1" (not verified)) by mx1.freebsd.org (Postfix) with ESMTPS id 4gtmQL03Dyz3RJH for ; Mon, 06 Jul 2026 01:06:18 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1783299978; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=3HGjzNe0SXSA1u3O4yPx/B+prykd68JnNKl/wdf55Cs=; b=po4KThEJC3vwC1jbrB6AxrqBwKr0TeV+52Jia5RBmfexhj5CcYhDqDBs1evVNd1XTo66Fe /DBOcF0JiWdIIPpWF749YiuUSWfcqN4Irs2hXfIlmijjD3Y4/EVYOspWih6iCgaUxh/ZJS 5BuS9X3+LHjAZckGSBBX03CAvztD8Y/OSvGCbHwqllBL36pHu1xxN9OyT1vjyg9BlKcrSW 6Gt9sAJaMFYN/14dilYy8ikRWuMd2phsYEUiVV/J2H/srWrIJrOqJ3AbiubhRl6s/f9HmX Gje2EaOccRpG2T9tGVjwzb39ZMdCwjC2d32UIHWBXr4/RDUvTt5SGUv/kFzMtA== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1783299978; a=rsa-sha256; cv=none; b=drtwSzALn2F/I3FIYA8JEhf1vStQcYMJ3ib2SQzEoGVBy69YTO53t5KzHe21rdsbfMeRLy Rr52/dJNFrqMiCSC/n34ChH5p/kV2kfRBxq1Um96/3aX7pzEO1qMTIR+kTZWx5q8ViNhrX InUiLBGdZZ24rdF0fnLZ8ndPQRfYdMqgVX2eKP9iSauZ80xLB82Yu399OVpxF6X5RnetCO mwcDnGKVQ7mUvfMZOCSyQnqdewR7sVfnwEHcs00LcQNYJfG9DW1h2EdQCH7l+2qsDibl3j kWBB6DCg6z4ZJxhWGW7fpG0ANvM2dvU9atUoFjEsjScemqHRzTccNA9MiImnyw== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1783299978; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=3HGjzNe0SXSA1u3O4yPx/B+prykd68JnNKl/wdf55Cs=; b=wnosNxR2NKJWJDnyhOcJ8MHkDYGABhr217Sxqp2KKBTTpQ77v0/ibxASNGSFdDT9ZbHGy8 ZdZXrP6ro2qwW4dX1Vrog4sxBCDJOM2YUK2nmA05t6MVBHaVaOSgpOmt29BJhlZjzJTBZB N3Jdn7gCz4XQ4+nSeMP1XovWg4QP26fB8Vzz9DSjCX/y77gfqmdMxuZiUmVcUuB5eAdudX 4QHjTC01qiS8L2sKMTUDr/orQ9vsj0g2PvUXhMuACWnuyjt0QQZQEIq03G6zjcrdisqHW0 /IqwrRFJdVzrheuS+5TV1rK/Bn72CpBKIPDTM+TXYVUsGgX+tdfHsY5AvPKMxw== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) by mxrelay.nyi.freebsd.org (Postfix) with ESMTP id 4gtmQK5bbZzjDl for ; Mon, 06 Jul 2026 01:06:17 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from git (uid 1279) (envelope-from git@FreeBSD.org) id 3a4a0 by gitrepo.freebsd.org (DragonFly Mail Agent v0.13+ on gitrepo.freebsd.org); Mon, 06 Jul 2026 01:06:17 +0000 To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org From: Konstantin Belousov Subject: git: 682ebe10032d - stable/15 - rtld: stop using unbound alloca() List-Id: Commit messages for all branches of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-all List-Help: List-Post: List-Subscribe: List-Unsubscribe: X-BeenThere: dev-commits-src-all@freebsd.org Sender: owner-dev-commits-src-all@FreeBSD.org List-Id: List-Post: List-Help: List-Subscribe: List-Unsubscribe: List-Owner: Precedence: list MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: kib X-Git-Repository: src X-Git-Refname: refs/heads/stable/15 X-Git-Reftype: branch X-Git-Commit: 682ebe10032d4e682381eb5f108a8297be7b682c Auto-Submitted: auto-generated Date: Mon, 06 Jul 2026 01:06:17 +0000 Message-Id: <6a4aff89.3a4a0.f4f7824@gitrepo.freebsd.org> The branch stable/15 has been updated by kib: URL: https://cgit.FreeBSD.org/src/commit/?id=682ebe10032d4e682381eb5f108a8297be7b682c commit 682ebe10032d4e682381eb5f108a8297be7b682c Author: Konstantin Belousov AuthorDate: 2026-06-27 15:11:37 +0000 Commit: Konstantin Belousov CommitDate: 2026-07-06 01:05:50 +0000 rtld: stop using unbound alloca() PR: 295991 (cherry picked from commit 1e370f038778e16c4b31f8992dda339d429e5cb8) --- libexec/rtld-elf/map_object.c | 4 ++- libexec/rtld-elf/rtld.c | 82 ++++++++++++++++++++++++++++++------------- libexec/rtld-elf/rtld.h | 2 ++ 3 files changed, 63 insertions(+), 25 deletions(-) diff --git a/libexec/rtld-elf/map_object.c b/libexec/rtld-elf/map_object.c index 6c6f0c9289b9..d769d01d3b24 100644 --- a/libexec/rtld-elf/map_object.c +++ b/libexec/rtld-elf/map_object.c @@ -113,7 +113,7 @@ map_object(int fd, const char *path, const struct stat *sb, bool ismain) note_end = 0; note_map = NULL; note_map_len = 0; - segs = alloca(sizeof(segs[0]) * hdr->e_phnum); + segs = xcalloc(hdr->e_phnum, sizeof(segs[0])); stack_flags = PF_X | PF_R | PF_W; text_end = 0; while (phdr < phlimit) { @@ -341,6 +341,7 @@ map_object(int fd, const char *path, const struct stat *sb, bool ismain) if (note_map != NULL) munmap(note_map, note_map_len); munmap(hdr, page_size); + free(segs); return (obj); error1: @@ -351,6 +352,7 @@ error: if (!phdr_in_zero_page(hdr)) munmap(phdr, hdr->e_phnum * sizeof(phdr[0])); munmap(hdr, page_size); + free(segs); return (NULL); } diff --git a/libexec/rtld-elf/rtld.c b/libexec/rtld-elf/rtld.c index 938e4b0b8a6b..864148df99ba 100644 --- a/libexec/rtld-elf/rtld.c +++ b/libexec/rtld-elf/rtld.c @@ -342,16 +342,6 @@ const char *ld_env_prefix = LD_; static void (*rtld_exit_ptr)(void); -/* - * Fill in a DoneList with an allocation large enough to hold all of - * the currently-loaded objects. Keep this as a macro since it calls - * alloca and we want that to occur within the scope of the caller. - */ -#define donelist_init(dlp) \ - ((dlp)->objs = alloca(obj_count * sizeof(dlp)->objs[0]), \ - assert((dlp)->objs != NULL), (dlp)->num_alloc = obj_count, \ - (dlp)->num_used = 0) - #define LD_UTRACE(e, h, mb, ms, r, n) \ do { \ if (ld_utrace != NULL) \ @@ -1042,6 +1032,38 @@ _rtld(Elf_Addr *sp, func_ptr_type *exit_proc, Obj_Entry **objp) return ((func_ptr_type)obj_main->entry); } +/* + * Fill in a DoneList with an allocation large enough to hold all of + * the currently-loaded Keep this as a macro since it calls + * alloca and we want that to occur within the scope of the caller. + */ +#define DLP_ALLOCA_LIMIT 100 /* 800 bytes on LP64 */ +#define donelist_init(_DLP, _REQ) do { \ + DoneList *_dlp = _DLP; \ + SymLook *_r = _REQ; \ + _dlp->num_alloc = obj_count, \ + _dlp->req = NULL; \ + if (_dlp->num_alloc > DLP_ALLOCA_LIMIT) { \ + _dlp->objs = xcalloc(_dlp->num_alloc, sizeof(_dlp->objs[0])); \ + if (_r != NULL && _r->donelist_mem == NULL) { \ + _r->donelist_mem = _dlp->objs; \ + _dlp->req = _r; \ + } \ + } else { \ + _dlp->objs = alloca(_dlp->num_alloc * sizeof(_dlp->objs[0])); \ + } \ + _dlp->num_used = 0; \ +} while (0) + +static void +donelist_free(DoneList *dlp) +{ + if (dlp->num_alloc > DLP_ALLOCA_LIMIT) + free(dlp->objs); + if (dlp->req != NULL) + dlp->req->donelist_mem = NULL; +} + void * rtld_resolve_ifunc(const Obj_Entry *obj, const Elf_Sym *def) { @@ -2319,7 +2341,7 @@ init_dag(Obj_Entry *root) if (root->dag_inited) return; - donelist_init(&donelist); + donelist_init(&donelist, NULL); /* Root object belongs to own DAG. */ objlist_push_tail(&root->dldags, root); @@ -2342,6 +2364,7 @@ init_dag(Obj_Entry *root) } } root->dag_inited = true; + donelist_free(&donelist); } static void @@ -4103,8 +4126,11 @@ do_dlsym(void *handle, const char *name, void *retaddr, const Ver_Entry *ve, LD_UTRACE(UTRACE_DLSYM_START, handle, NULL, 0, 0, name); rlock_acquire(rtld_bind_lock, &lockstate); - if (sigsetjmp(lockstate.env, 0) != 0) + if (sigsetjmp(lockstate.env, 0) != 0) { lock_upgrade(rtld_bind_lock, &lockstate); + free(req.donelist_mem); + req.donelist_mem = NULL; + } if (handle == NULL || handle == RTLD_NEXT || handle == RTLD_DEFAULT || handle == RTLD_SELF) { if ((obj = obj_from_addr(retaddr)) == NULL) { @@ -4173,7 +4199,7 @@ do_dlsym(void *handle, const char *name, void *retaddr, const Ver_Entry *ve, return (NULL); } - donelist_init(&donelist); + donelist_init(&donelist, &req); if (obj->mainprog) { /* Handle obtained by dlopen(NULL, ...) implies global * scope. */ @@ -4204,6 +4230,7 @@ do_dlsym(void *handle, const char *name, void *retaddr, const Ver_Entry *ve, defobj = req.defobj_out; } } + donelist_free(&donelist); } if (def != NULL) { @@ -4731,21 +4758,24 @@ get_program_var_addr(const char *name, RtldLockState *lockstate) { SymLook req; DoneList donelist; + const void **res; symlook_init(&req, name); req.lockstate = lockstate; - donelist_init(&donelist); + donelist_init(&donelist, NULL); if (symlook_global(&req, &donelist) != 0) return (NULL); if (ELF_ST_TYPE(req.sym_out->st_info) == STT_FUNC) - return ((const void **)make_function_pointer(req.sym_out, - req.defobj_out)); + res = (const void **)make_function_pointer(req.sym_out, + req.defobj_out); else if (ELF_ST_TYPE(req.sym_out->st_info) == STT_GNU_IFUNC) - return ((const void **)rtld_resolve_ifunc(req.defobj_out, - req.sym_out)); + res = (const void **)rtld_resolve_ifunc(req.defobj_out, + req.sym_out); else - return ((const void **)(req.defobj_out->relocbase + - req.sym_out->st_value)); + res = (const void **)(req.defobj_out->relocbase + + req.sym_out->st_value); + donelist_free(&donelist); + return (res); } /* @@ -4820,7 +4850,7 @@ symlook_default(SymLook *req, const Obj_Entry *refobj) SymLook req1; int res; - donelist_init(&donelist); + donelist_init(&donelist, req); symlook_init_from_req(&req1, req); /* @@ -4873,6 +4903,7 @@ symlook_default(SymLook *req, const Obj_Entry *refobj) } } + donelist_free(&donelist); return (req->sym_out != NULL ? 0 : ESRCH); } @@ -4954,13 +4985,15 @@ symlook_obj_load_filtees(SymLook *req, SymLook *req1, const Obj_Entry *obj, Needed_Entry *needed) { DoneList donelist; - int flags; + int flags, res; flags = (req->flags & SYMLOOK_EARLY) != 0 ? RTLD_LO_EARLY : 0; load_filtees(__DECONST(Obj_Entry *, obj), flags, req->lockstate); - donelist_init(&donelist); + donelist_init(&donelist, NULL); symlook_init_from_req(req1, req); - return (symlook_needed(req1, needed, &donelist)); + res = symlook_needed(req1, needed, &donelist); + donelist_free(&donelist); + return (res); } /* @@ -6305,6 +6338,7 @@ symlook_init_from_req(SymLook *dst, const SymLook *src) dst->defobj_out = NULL; dst->sym_out = NULL; dst->lockstate = src->lockstate; + dst->donelist_mem = NULL; } static int diff --git a/libexec/rtld-elf/rtld.h b/libexec/rtld-elf/rtld.h index 322d1ee94d6f..bdcfc3dc5ded 100644 --- a/libexec/rtld-elf/rtld.h +++ b/libexec/rtld-elf/rtld.h @@ -319,6 +319,7 @@ typedef struct Struct_SymCache { */ typedef struct Struct_DoneList { const Obj_Entry **objs; /* Array of object pointers */ + struct Struct_SymLook *req; unsigned int num_alloc; /* Allocated size of the array */ unsigned int num_used; /* Number of array slots used */ } DoneList; @@ -348,6 +349,7 @@ typedef struct Struct_SymLook { const Obj_Entry *defobj_out; const Elf_Sym *sym_out; struct Struct_RtldLockState *lockstate; + void *donelist_mem; } SymLook; enum {