Compare commits

..

2 Commits

Author SHA1 Message Date
Leah Rowe 049ee793db nvmutil: macro safety
maximum safety.

Signed-off-by: Leah Rowe <leah@libreboot.org>
2026-05-26 21:46:07 +01:00
Leah Rowe bc4bc4b67e nvmutil: fix error exits
ii used to rely on errno for exit status, but this was flawed.

when removing it, i neglected to adjust the actual error exits,
setting errno accordingly. this patch should fix it. this is
important for scripts that use nvmutil, which may rely on its
error status upon exit.

Signed-off-by: Leah Rowe <leah@libreboot.org>
2026-05-26 18:48:27 +01:00
+53 -19
View File
@@ -77,26 +77,41 @@ op_t op[] = {
}; };
void (*cmd)(void) = NULL; void (*cmd)(void) = NULL;
#define err_if(x) if (x) err(EXIT_FAILURE, "%s", filename) #define err_if(x) \
do { \
if (x) { \
err(EXIT_FAILURE, "%s", filename); \
} \
} while(0)
#define xopen(f,l,p) \ #define xopen(f,l,p) \
do { \ do { \
if ((f = open_on_eintr(l, p)) == -1) \ if ((f = open_on_eintr(l, p)) == -1) { \
err(EXIT_FAILURE, "%s", l); \ err(EXIT_FAILURE, "%s", l); \
if (fstat(f, &st) == -1) \ } \
err(EXIT_FAILURE, "%s", l); \ if (fstat(f, &st) == -1) { \
err(EXIT_FAILURE, "%s", l); \
} \
} while(0) } while(0)
#define word(pos16, partnum) ((uint16_t *) gbe[partnum])[pos16] #define word(pos16, partnum) \
#define setWord(pos16, p, val16) if (word(pos16, p) != val16) \ (((uint16_t *) gbe[partnum])[pos16])
nvmPartChanged[p] = 1 | (word(pos16, p) = val16)
#define SUCCESS(x) ((x) >= 0) #define setWord(pos16, p, val16) \
do { \
if (word(pos16, p) != val16) { \
nvmPartChanged[p] = 1 | (word(pos16, p) = val16); \
} \
} while(0)
#define SUCCESS(x) \
((x) >= 0)
#define reset_caller_errno(return_value) \ #define reset_caller_errno(return_value) \
do { \ do { \
if (SUCCESS(return_value) && (!errno)) \ if (SUCCESS(return_value) && (!errno)) { \
errno = saved_errno; \ errno = saved_errno; \
} \
} while (0) } while (0)
int int
@@ -283,7 +298,7 @@ cmd_setmac(void)
if (mac_updated) if (mac_updated)
return; return;
errno = EINVAL; errno = ECANCELED;
err(EXIT_FAILURE, "Error updating MAC address"); err(EXIT_FAILURE, "Error updating MAC address");
} }
@@ -376,6 +391,11 @@ cmd_dump(void)
printf("MAC (part %d): ", partnum); printf("MAC (part %d): ", partnum);
macf(partnum); macf(partnum);
hexdump(partnum); hexdump(partnum);
if (numInvalid > 1) {
errno = EINVAL;
err(EXIT_FAILURE, "dump: No valid checksums");
}
} }
} }
@@ -407,6 +427,7 @@ hexdump(int partnum)
} }
} }
/* WARNING: Cannot fail. Make sure the file is valid. */
void void
cmd_setchecksum(void) cmd_setchecksum(void)
{ {
@@ -420,22 +441,30 @@ cmd_setchecksum(void)
void void
cmd_brick(void) cmd_brick(void)
{ {
if (goodChecksum(part)) if (goodChecksum(part)) {
setWord(NVM_CHECKSUM_WORD, part, setWord(NVM_CHECKSUM_WORD, part,
((word(NVM_CHECKSUM_WORD, part)) ^ 0xFF)); ((word(NVM_CHECKSUM_WORD, part)) ^ 0xFF));
} else {
errno = ECANCELED;
err(EXIT_FAILURE, "brick: Bad checksum in part %d", part);
}
} }
void void
cmd_copy(void) cmd_copy(void)
{ {
nvmPartChanged[part ^ 1] = goodChecksum(part); nvmPartChanged[part ^ 1] = goodChecksum(part);
if (!nvmPartChanged[part ^ 1]) {
errno = ECANCELED;
err(EXIT_FAILURE, "copy: Bad checksum in part %d", part);
}
} }
void void
cmd_swap(void) { cmd_swap(void) {
if(!(goodChecksum(0) || goodChecksum(1))) { if(!(goodChecksum(0) || goodChecksum(1))) {
errno = EINVAL; errno = ECANCELED;
err(EXIT_FAILURE, "Invalid checksums"); err(EXIT_FAILURE, "swap: Bad checksums");
} }
gbe[0] ^= gbe[1]; gbe[0] ^= gbe[1];
@@ -502,8 +531,10 @@ xclose(int *fd)
int saved_errno = errno; int saved_errno = errno;
int rval = 0; int rval = 0;
if (fd == NULL) if (fd == NULL) {
errno = EBADF;
err(EXIT_FAILURE, "xclose: null pointer"); err(EXIT_FAILURE, "xclose: null pointer");
}
if (*fd < 0) if (*fd < 0)
return; return;
@@ -710,21 +741,24 @@ if_err_sys(int condition)
#define fs_err_retry() \ #define fs_err_retry() \
do { \ do { \
if ((rval == -1) && \ if ((rval == -1) && \
(errno == EINTR)) \ (errno == EINTR)) { \
return 1; \ return 1; \
if (rval >= 0 && !errno) \ } \
if (rval >= 0 && !errno) { \
errno = saved_errno; \ errno = saved_errno; \
return 0; \ } \
} while(0) } while(0)
int int
fs_retry(int saved_errno, int rval) fs_retry(int saved_errno, int rval)
{ {
fs_err_retry(); fs_err_retry();
return 0;
} }
int int
rw_retry(int saved_errno, ssize_t rval) rw_retry(int saved_errno, ssize_t rval)
{ {
fs_err_retry(); fs_err_retry();
return 0;
} }