From nobody Tue Jan 27 14:11:13 2026 X-Original-To: dev-commits-src-branches@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 4f0nPs5m2Qz6Pt8c for ; Tue, 27 Jan 2026 14:11:13 +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 "R13" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4f0nPs4NnMz3rts for ; Tue, 27 Jan 2026 14:11:13 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1769523073; 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=nislsYMZSoscSEDr7C/rkqFgnIW9FxCqKCLC1gvMEEw=; b=W5BcnmVowGv239noHNH/sQAtn7gDBQssdgsfdBoHz1Ag0GS1JXyJPC5botRTyGUuY6k3ms tdRf78rURLlZuXCDLnFpxzQI7DQJWv6eaKzj1v7ByvOiWMFz8rfrf4iRhvZYkfzU85IhDm PCSDAoel7x0nj4esRqr4FMHOK1om6AenB7Sy2r3DB65pJPd+dGU0PnZI6GrT2XV9ZZd/Dj LHrdfGEDeiY3sUTNaFUXDzolgx5X4XNPdftRjFTGgLsptvOuGTtxS6CybTCEpiGXTZwBvx JibfssH6v/jNb4ZdEW5WFl8rL3j4BGjy+5LVQyDJ+P8rKqM3UAanLucjALZUfw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1769523073; 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=nislsYMZSoscSEDr7C/rkqFgnIW9FxCqKCLC1gvMEEw=; b=O3gOvqfzsqabGadO7EdiKDb2qzqCpHXJiuCTN66htg2xGyhPVzO2sZGMihdRdPBYAMVnp8 h/YhOeK4MvRY/LJRtsQ8mCPkghXIQtBe89tnWdLVkOS573IHAp9br+BCKfJhDwpJRLMixr +nP+ZFn+aa/JPnrPKWkGR7m2xGREa9a6ttUV5dbZxR9QrIxCzkU5kyDbk2iFpUrfXPKpMw xgtG0w5IPgAAfOfZVSYP7cMChK9Cjme7Wb6EoZnUX+JdMJ5Xbc/tCJoXwkMYmzBYGyQyfH 2xbPmr5LzIqKKyeXN8mLPrGHqqAIcXXKo3r3K+o06YY2HCJmnMYLsFXozjxIXQ== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1769523073; a=rsa-sha256; cv=none; b=fyfwIVBqhE5Quv2TfEUxYAoFb264jekjoGxgx9fxi+O358CL4BUmCgxlyLLk9kL9gckjqF r0zvJhiA6MTVlrJb5wwn1tHrC4IY6hkBAe+lXzWRBJ5k51i9bAoupYNHIgWe0NCFdDhNa2 3GNQSkxIDAribvYvvhsKH+Tgza0xR9+uK2w886oPJmPC1H/mWD5NVvIQSwOQoIIffgYCbA olf2mE8eCbgK2Gt78QIbJHOWcaNUrf2zwrTJFT97ZvUKeoVqp7NZziowQHywZHAaVsUyht 03GLB3gd8+bqpT2kUycjj9wqOYMuzQn8s6n+TQc2Qub7NX3ZWEM8QxIhT9gZDA== ARC-Authentication-Results: i=1; mx1.freebsd.org; none Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) by mxrelay.nyi.freebsd.org (Postfix) with ESMTP id 4f0nPs3vl1z18kF for ; Tue, 27 Jan 2026 14:11:13 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from git (uid 1279) (envelope-from git@FreeBSD.org) id 23de7 by gitrepo.freebsd.org (DragonFly Mail Agent v0.13+ on gitrepo.freebsd.org); Tue, 27 Jan 2026 14:11:13 +0000 To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org From: Mark Johnston Subject: git: d76fb46307da - stable/15 - linker: Reset DMAP protections in link_elf_unload_file() List-Id: Commits to the stable branches of the FreeBSD src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-branches List-Help: List-Post: List-Subscribe: List-Unsubscribe: X-BeenThere: dev-commits-src-branches@freebsd.org Sender: owner-dev-commits-src-branches@FreeBSD.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: markj X-Git-Repository: src X-Git-Refname: refs/heads/stable/15 X-Git-Reftype: branch X-Git-Commit: d76fb46307da290e6494d387a3b8fc065a87f806 Auto-Submitted: auto-generated Date: Tue, 27 Jan 2026 14:11:13 +0000 Message-Id: <6978c781.23de7.5403df21@gitrepo.freebsd.org> The branch stable/15 has been updated by markj: URL: https://cgit.FreeBSD.org/src/commit/?id=d76fb46307da290e6494d387a3b8fc065a87f806 commit d76fb46307da290e6494d387a3b8fc065a87f806 Author: Mark Johnston AuthorDate: 2026-01-06 16:48:54 +0000 Commit: Mark Johnston CommitDate: 2026-01-27 14:10:48 +0000 linker: Reset DMAP protections in link_elf_unload_file() On x86, when a preloaded kernel module is unloaded, we free the backing (physically contiguous) pages. The ET_REL linker will have adjusted protections on segments of the preloaded file, which updates the direct map, so the original protections must be restored when unloading the module. Previously this was handled in kmem_bootstrap_free(), but there is no apparent reason not to handle this within the kernel linker. Moreover, we were not resetting permissions in the kernel map on arm64. Reviewed by: alc, kib MFC after: 3 weeks Differential Revision: https://reviews.freebsd.org/D54438 (cherry picked from commit 203e5a1eeec1153b0bcb230ccfb90531fa8cbeb5) --- sys/kern/link_elf.c | 46 +++++++++++++++++++++++++++++++++------------- sys/kern/link_elf_obj.c | 14 ++++++++++++++ sys/vm/vm_kern.c | 8 -------- 3 files changed, 47 insertions(+), 21 deletions(-) diff --git a/sys/kern/link_elf.c b/sys/kern/link_elf.c index ebd203858b66..45edd186e6ce 100644 --- a/sys/kern/link_elf.c +++ b/sys/kern/link_elf.c @@ -155,7 +155,7 @@ static int link_elf_search_symbol(linker_file_t, caddr_t, c_linker_sym_t *, long *); static void link_elf_unload_file(linker_file_t); -static void link_elf_unload_preload(linker_file_t); +static void link_elf_unload_preload(elf_file_t); static int link_elf_lookup_set(linker_file_t, const char *, void ***, void ***, int *); static int link_elf_each_function_name(linker_file_t, @@ -799,10 +799,10 @@ parse_vnet(elf_file_t ef) /* * Apply the specified protection to the loadable segments of a preloaded linker - * file. + * file. If "reset" is not set, the original segment protections are ORed in. */ static int -preload_protect(elf_file_t ef, vm_prot_t prot) +preload_protect1(elf_file_t ef, vm_prot_t prot, bool reset) { #if defined(__aarch64__) || defined(__amd64__) Elf_Ehdr *hdr; @@ -818,13 +818,16 @@ preload_protect(elf_file_t ef, vm_prot_t prot) if (phdr->p_type != PT_LOAD) continue; - nprot = prot | VM_PROT_READ; - if ((phdr->p_flags & PF_W) != 0) - nprot |= VM_PROT_WRITE; - if ((phdr->p_flags & PF_X) != 0) - nprot |= VM_PROT_EXECUTE; + nprot = VM_PROT_NONE; + if (!reset) { + nprot = VM_PROT_READ; + if ((phdr->p_flags & PF_W) != 0) + nprot |= VM_PROT_WRITE; + if ((phdr->p_flags & PF_X) != 0) + nprot |= VM_PROT_EXECUTE; + } error = pmap_change_prot((vm_offset_t)ef->address + - phdr->p_vaddr, round_page(phdr->p_memsz), nprot); + phdr->p_vaddr, round_page(phdr->p_memsz), prot | nprot); if (error != 0) break; } @@ -834,6 +837,18 @@ preload_protect(elf_file_t ef, vm_prot_t prot) #endif } +static int +preload_protect(elf_file_t ef, vm_prot_t prot) +{ + return (preload_protect1(ef, prot, false)); +} + +static int +preload_protect_reset(elf_file_t ef, vm_prot_t prot) +{ + return (preload_protect1(ef, prot, true)); +} + #ifdef __arm__ /* * Locate the ARM exception/unwind table info for DDB and stack(9) use by @@ -1396,7 +1411,7 @@ link_elf_unload_file(linker_file_t file) elf_cpu_unload_file(file); if (ef->preloaded) { - link_elf_unload_preload(file); + link_elf_unload_preload(ef); return; } @@ -1417,11 +1432,16 @@ link_elf_unload_file(linker_file_t file) } static void -link_elf_unload_preload(linker_file_t file) +link_elf_unload_preload(elf_file_t ef) { + /* + * Reset mapping protections to their original state. This affects the + * direct map alias of the module mapping as well. + */ + preload_protect_reset(ef, VM_PROT_RW); - if (file->pathname != NULL) - preload_delete_name(file->pathname); + if (ef->lf.pathname != NULL) + preload_delete_name(ef->lf.pathname); } static const char * diff --git a/sys/kern/link_elf_obj.c b/sys/kern/link_elf_obj.c index a3a53a39bfd6..4128baa5a909 100644 --- a/sys/kern/link_elf_obj.c +++ b/sys/kern/link_elf_obj.c @@ -1305,6 +1305,20 @@ link_elf_unload_file(linker_file_t file) vnet_data_free(ef->progtab[i].addr, ef->progtab[i].size); #endif + else if (ef->preloaded) { + vm_offset_t start, end; + + start = (vm_offset_t)ef->progtab[i].addr; + end = start + ef->progtab[i].size; + + /* + * Reset mapping protections to their original + * state. This affects the direct map alias of + * the module mapping as well. + */ + link_elf_protect_range(ef, trunc_page(start), + round_page(end), VM_PROT_RW); + } } } if (ef->preloaded) { diff --git a/sys/vm/vm_kern.c b/sys/vm/vm_kern.c index ac327aa37b72..626632b74add 100644 --- a/sys/vm/vm_kern.c +++ b/sys/vm/vm_kern.c @@ -953,14 +953,6 @@ kmem_bootstrap_free(vm_offset_t start, vm_size_t size) end = trunc_page(start + size); start = round_page(start); -#ifdef __amd64__ - /* - * Preloaded files do not have execute permissions by default on amd64. - * Restore the default permissions to ensure that the direct map alias - * is updated. - */ - pmap_change_prot(start, end - start, VM_PROT_RW); -#endif for (va = start; va < end; va += PAGE_SIZE) { pa = pmap_kextract(va); m = PHYS_TO_VM_PAGE(pa);