aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJessica Clarke <jrtc27@FreeBSD.org>2024-02-23 02:36:21 +0000
committerJessica Clarke <jrtc27@FreeBSD.org>2024-02-23 02:36:21 +0000
commit09cb8031b43c8e98abb5ff9b43ff649031d1e808 (patch)
treedbdd7eeabbb0aff9974543d8cf00a290f8740861
parent04eca69323111986b262eef3135d804361b60d17 (diff)
downloadsrc-09cb8031b43c8e98abb5ff9b43ff649031d1e808.tar.gz
src-09cb8031b43c8e98abb5ff9b43ff649031d1e808.zip
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
-rw-r--r--usr.sbin/efibootmgr/efibootmgr.c21
1 files changed, 7 insertions, 14 deletions
diff --git a/usr.sbin/efibootmgr/efibootmgr.c b/usr.sbin/efibootmgr/efibootmgr.c
index 7bcb4674586b..2bc79ee26f51 100644
--- a/usr.sbin/efibootmgr/efibootmgr.c
+++ b/usr.sbin/efibootmgr/efibootmgr.c
@@ -561,7 +561,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;
@@ -579,21 +579,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;