Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 15 Dec 2025 18:18:25 +0000
From:      Jessica Clarke <jrtc27@FreeBSD.org>
To:        src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org
Subject:   git: c4f666e81c6e - stable/13 - efibootmgr: Simplify make_next_boot_var_name and fix cnt == 0 case
Message-ID:  <694050f1.25a2a.2e97ba0a@gitrepo.freebsd.org>

index | next in thread | raw e-mail

The branch stable/13 has been updated by jrtc27:

URL: https://cgit.FreeBSD.org/src/commit/?id=c4f666e81c6e7c4b726d7c5ff34a95e652848914

commit c4f666e81c6e7c4b726d7c5ff34a95e652848914
Author:     Jessica Clarke <jrtc27@FreeBSD.org>
AuthorDate: 2024-02-23 02:36:21 +0000
Commit:     Jessica Clarke <jrtc27@FreeBSD.org>
CommitDate: 2025-12-15 17:56:34 +0000

    efibootmgr: Simplify make_next_boot_var_name and fix cnt == 0 case
    
    If cnt == 0 we access element 0 unconditionally, which is out of bounds,
    and then if that doesn't crash and happens to be 0 we will access
    element - 1, also out of bounds, and then if that doesn't crash will add
    1 to whatever junk is there and use that for the variable. On CHERI,
    though, this does crash. This code is also overly complicated, with
    unnecessary special cases and tracking more state than needed.
    
    Rewrite it in a more general manner that doesn't need those special
    cases and naturally works for cnt == 0.
    
    Found by:       CHERI
    Reviewed by:    imp
    Fixes:          1285bcc833a3 ("Import Netflix's efibootmgr to help manage UEFI boot variables")
    MFC after:      1 week
    Differential Revision:  https://reviews.freebsd.org/D44029
    
    (cherry picked from commit 09cb8031b43c8e98abb5ff9b43ff649031d1e808)
---
 usr.sbin/efibootmgr/efibootmgr.c | 21 +++++++--------------
 1 file changed, 7 insertions(+), 14 deletions(-)

diff --git a/usr.sbin/efibootmgr/efibootmgr.c b/usr.sbin/efibootmgr/efibootmgr.c
index dfe8bfb1c145..74b59863d6c5 100644
--- a/usr.sbin/efibootmgr/efibootmgr.c
+++ b/usr.sbin/efibootmgr/efibootmgr.c
@@ -555,7 +555,7 @@ static char *
 make_next_boot_var_name(void)
 {
 	struct entry *v;
-	uint16_t *vals, next_free = 0;
+	uint16_t *vals;
 	char *name;
 	int cnt = 0;
 	int i;
@@ -573,21 +573,14 @@ make_next_boot_var_name(void)
 		vals[i++] = v->idx;
 	}
 	qsort(vals, cnt, sizeof(uint16_t), compare);
-	/* if the hole is at the beginning, just return zero */
-	if (vals[0] > 0) {
-		next_free = 0;
-	} else {
-		/* now just run the list looking for the first hole */
-		for (i = 0; i < cnt - 1 && next_free == 0; i++)
-			if (vals[i] + 1 != vals[i + 1])
-				next_free = vals[i] + 1;
-		if (next_free == 0)
-			next_free = vals[cnt - 1] + 1;
-		/* In theory we could have used all 65k slots -- what to do? */
-	}
+	/* Find the first hole (could be at start or end) */
+	for (i = 0; i < cnt; ++i)
+		if (vals[i] != i)
+			break;
 	free(vals);
+	/* In theory we could have used all 65k slots -- what to do? */
 
-	asprintf(&name, "%s%04X", "Boot", next_free);
+	asprintf(&name, "%s%04X", "Boot", i);
 	if (name == NULL)
 		err(1, "asprintf");
 	return name;


help

Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?694050f1.25a2a.2e97ba0a>