From nobody Sun Dec 12 14:30:32 2021 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 D9C1918E8BF8; Sun, 12 Dec 2021 14:30:34 +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 "R3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4JBn9j3Xgkz4mZ2; Sun, 12 Dec 2021 14:30:33 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (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 did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 07B9A229D3; Sun, 12 Dec 2021 14:30:33 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.16.1/8.16.1) with ESMTP id 1BCEUWie066640; Sun, 12 Dec 2021 14:30:32 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.16.1/8.16.1/Submit) id 1BCEUWMI066639; Sun, 12 Dec 2021 14:30:32 GMT (envelope-from git) Date: Sun, 12 Dec 2021 14:30:32 GMT Message-Id: <202112121430.1BCEUWMI066639@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: Konstantin Belousov Subject: git: 9cf78c1cf6e8 - main - elf image activator: convert asserts into errors 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: Sender: owner-dev-commits-src-all@freebsd.org X-BeenThere: dev-commits-src-all@freebsd.org 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/main X-Git-Reftype: branch X-Git-Commit: 9cf78c1cf6e8909e4b5eaedeb86482904c0bbdc4 Auto-Submitted: auto-generated ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1639319433; 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=a0vHGtD0vkiMseFpeYys+h/mjh+IiRDFEwMWSb57alk=; b=l64wFIs0Bc/971XoqNgCR5kHOMg8mZmnsoTbW9/3JNs1JW5G9JLFqLGzAIr62mJX1XF0ZV KRDAy4izefJPV/3EjZJ9UbVYeTMbiW95dd0YPQ6VjVqbd7rWFhbJbDrufZDsI3QyuE+qSV NOS+g0JVavEbBj8lYCOtFadlSvhuRI8v+1hjkcN21j0LQzsWKnDtmKKGPGOPCfwvBLrQxu 9jesb77dsmJouuPmKkvJ2kNxf6aPBnkVvRw1qrklJTjU/Zq2bDYF45BR9yC6VEbevv3pql 5VBLJlXjm9GoeI5hlNqkvii/6sshl1uu5uxy42XYhRObFKHoRql8dP6b6HWbAg== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1639319433; a=rsa-sha256; cv=none; b=K/CEVlIr5K6bf4Lw54netBCrfu3/Rjs5Tr/QmhLIZkeAsZBuey9ON6n1dPkIkDvHSpOE85 x1vCd/ntVWk337NRV3HjE6G7PsPItDBZzpbbQsbyGvM0bwceEElD1ZaQ2yANtWFLSoy25R 47mvSoNkOswLz+IUuBeXRBff7hEtwV85vUUWyjh5RGANrDzyNPVx6V9OxrFKKSTBpI92c1 oI031bFUG/HYNd55R7SXKMg39FFr3ByR6S407ccmQuS4L1KMHeVmi8WoeqfqYba7IrQ42o Our6sizbgMy/rT6MAU1gCSPGs3Rwgdhsj6aDKS+Nown1gYcNkrtkhBd5fh9VDA== ARC-Authentication-Results: i=1; mx1.freebsd.org; none X-ThisMailContainsUnwantedMimeParts: N The branch main has been updated by kib: URL: https://cgit.FreeBSD.org/src/commit/?id=9cf78c1cf6e8909e4b5eaedeb86482904c0bbdc4 commit 9cf78c1cf6e8909e4b5eaedeb86482904c0bbdc4 Author: Konstantin Belousov AuthorDate: 2021-12-07 09:29:53 +0000 Commit: Konstantin Belousov CommitDate: 2021-12-12 14:28:38 +0000 elf image activator: convert asserts into errors Invalid (artificial) layout of the loadable ELF segments might result in triggering the assertion. This means that the file should not be executed, regardless of the kernel debug mode. Change calling conventions for rnd_elf{32,64} helpers to allow returning an error, and abort activation with ENOEXEC if its invariants are broken. Reported and tested by: pho Reviewed by: markj Sponsored by: The FreeBSD Foundation MFC after: 1 week Differential revision: https://reviews.freebsd.org/D33359 --- sys/kern/imgact_elf.c | 44 ++++++++++++++++++++++++++------------------ 1 file changed, 26 insertions(+), 18 deletions(-) diff --git a/sys/kern/imgact_elf.c b/sys/kern/imgact_elf.c index 3fe87fe08f5e..6fcfef4050bb 100644 --- a/sys/kern/imgact_elf.c +++ b/sys/kern/imgact_elf.c @@ -875,28 +875,34 @@ fail: return (error); } -static u_long -__CONCAT(rnd_, __elfN(base))(vm_map_t map __unused, u_long minv, u_long maxv, - u_int align) +static int +__CONCAT(rnd_, __elfN(base))(vm_map_t map, u_long minv, u_long maxv, + u_int align, u_long *resp) { u_long rbase, res; MPASS(vm_map_min(map) <= minv); - MPASS(maxv <= vm_map_max(map)); - MPASS(minv < maxv); - MPASS(minv + align < maxv); + + if (minv >= maxv || minv + align >= maxv || maxv > vm_map_max(map)) { + uprintf("Invalid ELF segments layout\n"); + return (ENOEXEC); + } + arc4rand(&rbase, sizeof(rbase), 0); res = roundup(minv, (u_long)align) + rbase % (maxv - minv); res &= ~((u_long)align - 1); if (res >= maxv) res -= align; + KASSERT(res >= minv, ("res %#lx < minv %#lx, maxv %#lx rbase %#lx", res, minv, maxv, rbase)); KASSERT(res < maxv, ("res %#lx > maxv %#lx, minv %#lx rbase %#lx", res, maxv, minv, rbase)); - return (res); + + *resp = res; + return (0); } static int @@ -1276,13 +1282,13 @@ __CONCAT(exec_, __elfN(imgact))(struct image_params *imgp) imgp->proc->p_elf_brandinfo = brand_info; maxv = vm_map_max(map) - lim_max(td, RLIMIT_STACK); - if (et_dyn_addr == ET_DYN_ADDR_RAND) { + if (error == 0 && et_dyn_addr == ET_DYN_ADDR_RAND) { KASSERT((map->flags & MAP_ASLR) != 0, ("ET_DYN_ADDR_RAND but !MAP_ASLR")); - et_dyn_addr = __CONCAT(rnd_, __elfN(base))(map, + error = __CONCAT(rnd_, __elfN(base))(map, vm_map_min(map) + mapsz + lim_max(td, RLIMIT_DATA), /* reserve half of the address space to interpreter */ - maxv / 2, 1UL << flsl(maxalign)); + maxv / 2, 1UL << flsl(maxalign), &et_dyn_addr); } vn_lock(imgp->vp, LK_SHARED | LK_RETRY); @@ -1309,10 +1315,11 @@ __CONCAT(exec_, __elfN(imgact))(struct image_params *imgp) RLIMIT_DATA)); if ((map->flags & MAP_ASLR) != 0) { maxv1 = maxv / 2 + addr / 2; - MPASS(maxv1 >= addr); /* No overflow */ - map->anon_loc = __CONCAT(rnd_, __elfN(base))(map, addr, maxv1, + error = __CONCAT(rnd_, __elfN(base))(map, addr, maxv1, (MAXPAGESIZES > 1 && pagesizes[1] != 0) ? - pagesizes[1] : pagesizes[0]); + pagesizes[1] : pagesizes[0], &map->anon_loc); + if (error != 0) + goto ret; } else { map->anon_loc = addr; } @@ -1324,12 +1331,13 @@ __CONCAT(exec_, __elfN(imgact))(struct image_params *imgp) if ((map->flags & MAP_ASLR) != 0) { /* Assume that interpreter fits into 1/4 of AS */ maxv1 = maxv / 2 + addr / 2; - MPASS(maxv1 >= addr); /* No overflow */ - addr = __CONCAT(rnd_, __elfN(base))(map, addr, - maxv1, PAGE_SIZE); + error = __CONCAT(rnd_, __elfN(base))(map, addr, + maxv1, PAGE_SIZE, &addr); + } + if (error == 0) { + error = __elfN(load_interp)(imgp, brand_info, interp, + &addr, &imgp->entry_addr); } - error = __elfN(load_interp)(imgp, brand_info, interp, &addr, - &imgp->entry_addr); vn_lock(imgp->vp, LK_SHARED | LK_RETRY); if (error != 0) goto ret;