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
+50 -16
View File
@@ -77,26 +77,41 @@ op_t op[] = {
};
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) \
do { \
if ((f = open_on_eintr(l, p)) == -1) \
if ((f = open_on_eintr(l, p)) == -1) { \
err(EXIT_FAILURE, "%s", l); \
if (fstat(f, &st) == -1) \
} \
if (fstat(f, &st) == -1) { \
err(EXIT_FAILURE, "%s", l); \
} \
} while(0)
#define word(pos16, partnum) ((uint16_t *) gbe[partnum])[pos16]
#define setWord(pos16, p, val16) if (word(pos16, p) != val16) \
nvmPartChanged[p] = 1 | (word(pos16, p) = val16)
#define word(pos16, partnum) \
(((uint16_t *) gbe[partnum])[pos16])
#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) \
do { \
if (SUCCESS(return_value) && (!errno)) \
if (SUCCESS(return_value) && (!errno)) { \
errno = saved_errno; \
} \
} while (0)
int
@@ -283,7 +298,7 @@ cmd_setmac(void)
if (mac_updated)
return;
errno = EINVAL;
errno = ECANCELED;
err(EXIT_FAILURE, "Error updating MAC address");
}
@@ -376,6 +391,11 @@ cmd_dump(void)
printf("MAC (part %d): ", partnum);
macf(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
cmd_setchecksum(void)
{
@@ -420,22 +441,30 @@ cmd_setchecksum(void)
void
cmd_brick(void)
{
if (goodChecksum(part))
if (goodChecksum(part)) {
setWord(NVM_CHECKSUM_WORD, part,
((word(NVM_CHECKSUM_WORD, part)) ^ 0xFF));
} else {
errno = ECANCELED;
err(EXIT_FAILURE, "brick: Bad checksum in part %d", part);
}
}
void
cmd_copy(void)
{
nvmPartChanged[part ^ 1] = goodChecksum(part);
if (!nvmPartChanged[part ^ 1]) {
errno = ECANCELED;
err(EXIT_FAILURE, "copy: Bad checksum in part %d", part);
}
}
void
cmd_swap(void) {
if(!(goodChecksum(0) || goodChecksum(1))) {
errno = EINVAL;
err(EXIT_FAILURE, "Invalid checksums");
errno = ECANCELED;
err(EXIT_FAILURE, "swap: Bad checksums");
}
gbe[0] ^= gbe[1];
@@ -502,8 +531,10 @@ xclose(int *fd)
int saved_errno = errno;
int rval = 0;
if (fd == NULL)
if (fd == NULL) {
errno = EBADF;
err(EXIT_FAILURE, "xclose: null pointer");
}
if (*fd < 0)
return;
@@ -710,21 +741,24 @@ if_err_sys(int condition)
#define fs_err_retry() \
do { \
if ((rval == -1) && \
(errno == EINTR)) \
(errno == EINTR)) { \
return 1; \
if (rval >= 0 && !errno) \
} \
if (rval >= 0 && !errno) { \
errno = saved_errno; \
return 0; \
} \
} while(0)
int
fs_retry(int saved_errno, int rval)
{
fs_err_retry();
return 0;
}
int
rw_retry(int saved_errno, ssize_t rval)
{
fs_err_retry();
return 0;
}