summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore2
-rw-r--r--util/nvmutil/.gitignore3
-rw-r--r--util/nvmutil/ChangeLog.md8
-rw-r--r--util/nvmutil/Makefile2
-rw-r--r--util/nvmutil/README.md4
-rw-r--r--util/nvmutil/nvmutil.c122
6 files changed, 82 insertions, 59 deletions
diff --git a/.gitignore b/.gitignore
index e5085ba5..43285fbc 100644
--- a/.gitignore
+++ b/.gitignore
@@ -30,8 +30,6 @@
*me.bin
*sch5545ec.bin
/mrc/
-/util/nvmutil/nvm
-/util/nvmutil/nvmutil
/src/
/CHANGELOG
/todo.txt
diff --git a/util/nvmutil/.gitignore b/util/nvmutil/.gitignore
new file mode 100644
index 00000000..802202a4
--- /dev/null
+++ b/util/nvmutil/.gitignore
@@ -0,0 +1,3 @@
+/nvm
+/nvmutil
+*.bin
diff --git a/util/nvmutil/ChangeLog.md b/util/nvmutil/ChangeLog.md
deleted file mode 100644
index e1ed5754..00000000
--- a/util/nvmutil/ChangeLog.md
+++ /dev/null
@@ -1,8 +0,0 @@
-This change log has moved. Please refer here for historical pre-osboot-merge
-changes:
-
-<https://libreboot.org/docs/install/nvmutilimport.html>
-
-Osboot merged with Libreboot on November 17th, 2022. For nvmutil changes after
-this date, please check regular Libreboot release announcements which shall
-now specify any such changes.
diff --git a/util/nvmutil/Makefile b/util/nvmutil/Makefile
index 9bc0e381..22376c70 100644
--- a/util/nvmutil/Makefile
+++ b/util/nvmutil/Makefile
@@ -3,7 +3,7 @@
# SPDX-FileCopyrightText: 2023 Riku Viitanen <riku.viitanen@protonmail.com>
CC?=cc
-CFLAGS?=-Os -Wall -Wextra -Werror -pedantic -std=c99 -D_POSIX_C_SOURCE=200809L
+CFLAGS?=-Os -Wall -Wextra -Werror -pedantic -std=c99
DESTDIR?=
PREFIX?=/usr/local
INSTALL?=install
diff --git a/util/nvmutil/README.md b/util/nvmutil/README.md
deleted file mode 100644
index 03a25bc4..00000000
--- a/util/nvmutil/README.md
+++ /dev/null
@@ -1,4 +0,0 @@
-
-This documentation has become part of lbwww. See:
-
-<https://libreboot.org/docs/install/nvmutil.html>
diff --git a/util/nvmutil/nvmutil.c b/util/nvmutil/nvmutil.c
index b8ea2376..03aa3c20 100644
--- a/util/nvmutil/nvmutil.c
+++ b/util/nvmutil/nvmutil.c
@@ -1,24 +1,36 @@
-/* SPDX-License-Identifier: MIT */
-/* Copyright (c) 2022-2026 Leah Rowe <leah@libreboot.org> */
-/* Copyright (c) 2023 Riku Viitanen <riku.viitanen@protonmail.com> */
-
-/*
- * Written for portability among the Unices (Linux, BSD etc)
+/* SPDX-License-Identifier: MIT
+ *
+ * Copyright (c) 2022-2026 Leah Rowe <leah@libreboot.org>
+ * Copyright (c) 2023 Riku Viitanen <riku.viitanen@protonmail.com>
+ *
+ * This tool lets you modify Intel GbE NVM (Gigabit Ethernet
+ * Non-Volatile Memory) images, e.g. change the MAC address.
+ * These images configure your Intel Gigabit Ethernet adapter.
+ *
+ * This code is designed to be portable, running on as many
+ * Unix and Unix-like systems as possible (mainly BSD/Linux).
+ *
+ * Recommended CFLAGS for Clang/GCC:
*
- * Use these CFLAGS:
- * -Os -Wall -Wextra -Werror -pedantic -std=c99 -D_POSIX_C_SOURCE=200809L
+ * -Os -Wall -Wextra -Werror -pedantic -std=c99
*/
-#define _POSIX_C_SOURCE 200809L
+#ifndef _XOPEN_SOURCE
+#define _XOPEN_SOURCE 500
+#endif
+
+#ifndef _FILE_OFFSET_BITS
+#define _FILE_OFFSET_BITS 64
+#endif
#ifdef __OpenBSD__
#include <sys/param.h>
#endif
+#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>
#include <fcntl.h>
-#include <inttypes.h>
#include <stdarg.h>
#include <stdint.h>
#include <stdio.h>
@@ -26,11 +38,20 @@
#include <string.h>
#include <unistd.h>
+#if __STDC_VERSION__ >= 201112L
+_Static_assert(sizeof(uint16_t) == 2, "uint16_t must be 16 bits");
+#else
+typedef char static_assert_uint16_t_is_2[(sizeof(uint16_t) == 2) ? 1 : -1];
+#endif
+
/*
* The BSD versions that could realistically build
* nvmutil almost certainly have arc4random (first
- * introduced in 1990s or early 2000s in most of
- * them - you can just patch as needed, on old BSD.
+ * introduced in 1990s to early 2000s).
+ *
+ * If you want it on another platform, e.g. Linux,
+ * just patch this accordingly. Or patch it to remove
+ * arc4random on old/weird Unix systems.
*/
#if defined(__OpenBSD__) || defined(__FreeBSD__) || \
defined(__NetBSD__) || defined(__APPLE__) || \
@@ -258,8 +279,8 @@ struct commands {
*/
static const struct commands command[] = {
/*
- * Unlike older versions, we now require
- * both checksums to be valid for "dump".
+ * Unlike older versions, we require at least
+ * one checksum to be valid when running dump.
*/
{ CMD_DUMP, "dump", cmd_helper_dump, ARGC_3,
NO_INVERT, SET_MOD_OFF,
@@ -333,14 +354,14 @@ main(int argc, char *argv[])
#ifdef NVMUTIL_UNVEIL
if (gbe_flags == O_RDONLY) {
if (unveil(fname, "r") == -1)
- err(ECANCELED, "unveil ro '%s'", fname);
+ err(ECANCELED, "%s: unveil ro", fname);
if (unveil(NULL, NULL) == -1)
err(ECANCELED, "unveil block (ro)");
if (pledge("stdio rpath", NULL) == -1)
err(ECANCELED, "pledge ro (kill unveil)");
} else {
if (unveil(fname, "rw") == -1)
- err(ECANCELED, "unveil rw '%s'", fname);
+ err(ECANCELED, "%s: unveil rw", fname);
if (unveil(NULL, NULL) == -1)
err(ECANCELED, "unveil block (rw)");
if (pledge("stdio rpath wpath", NULL) == -1)
@@ -376,7 +397,7 @@ main(int argc, char *argv[])
run_cmd(cmd_index);
if (errno)
- err(errno, "Unhandled error: will not write file: %s", fname);
+ err(errno, "%s: Unhandled error (WRITE SKIPPED)", fname);
else if (gbe_flags != O_RDONLY)
write_gbe_file();
@@ -694,10 +715,10 @@ read_gbe_file_part(size_t p)
if ((size_t)read_gbe_file_exact(gbe_fd, mem_offset,
gbe_rw_size, gbe_file_offset(p, "pread"), fname, "pread") !=
gbe_rw_size)
- err(ECANCELED, "Partial read p%zu, file %s", p, fname);
+ err(ECANCELED, "%s: Partial read from p%zu", fname, p);
- printf("Read %zu bytes from part %zu: %s\n",
- gbe_rw_size, p, fname);
+ printf("%s: Read %zu bytes from p%zu\n",
+ fname, gbe_rw_size, p);
}
static void
@@ -744,7 +765,7 @@ read_checksums(void)
errno = 0;
if (num_invalid >= max_invalid)
- err(ECANCELED, "No valid checksum found in file: %s",
+ err(ECANCELED, "%s: No valid checksum found in file",
fname);
}
@@ -909,16 +930,22 @@ rhex(void)
{
static size_t n = 0;
static uint8_t rnum[12];
+#ifndef NVMUTIL_ARC4RANDOM_BUF
+ int max_retries;
+#endif
+#ifdef NVMUTIL_ARC4RANDOM_BUF
if (!n) {
n = sizeof(rnum);
-#ifdef NVMUTIL_ARC4RANDOM_BUF
arc4random_buf(rnum, n);
+ }
#else
+ for (max_retries = 0; max_retries < 50 && !n; max_retries++)
n = (size_t)read_gbe_file_exact(urandom_fd,
- rnum, n, 0, rname, NULL);
+ rnum, sizeof(rnum), 0, rname, NULL);
+ if (!n || n > sizeof(rnum))
+ err(ECANCELED, "Randomisation failure");
#endif
- }
return (uint16_t)(rnum[--n] & 0xf);
}
@@ -945,6 +972,7 @@ read_gbe_file_exact(int fd, void *buf, size_t len,
}
if (rval != -1) {
+#ifndef NVMUTIL_ARC4RANDOM_BUF
if (fd == urandom_fd) {
/*
* /dev/[u]random reads can still return
@@ -956,10 +984,12 @@ read_gbe_file_exact(int fd, void *buf, size_t len,
* the smaller amount of bytes and call
* read_gbe_file_exact again if necessary.
*/
- if (rval > 0)
+ if (rval > 0) {
+ errno = 0;
return rval;
+ }
}
-
+#endif
err(ECANCELED,
"Short %s, %zd bytes, on file: %s",
op ? op : "read", rval, path);
@@ -973,6 +1003,7 @@ read_gbe_file_exact(int fd, void *buf, size_t len,
err(EINTR, "%s: max retries exceeded on file: %s",
op ? op : "read", path);
+
return -1;
}
@@ -1028,7 +1059,7 @@ hexdump(size_t partnum)
uint16_t val16;
for (row = 0; row < 8; row++) {
- printf("%08zx ", row << 4);
+ printf("%08zx ", (size_t)row << 4);
for (c = 0; c < 8; c++) {
val16 = nvm_word((row << 3) + c, partnum);
if (c == 4)
@@ -1104,12 +1135,12 @@ static uint16_t
calculated_checksum(size_t p)
{
size_t c;
- uint16_t val16 = 0;
+ uint32_t val16 = 0;
for (c = 0; c < NVM_CHECKSUM_WORD; c++)
- val16 += nvm_word(c, p);
+ val16 += (uint32_t)nvm_word(c, p);
- return NVM_CHECKSUM - val16;
+ return (uint16_t)((NVM_CHECKSUM - val16) & 0xffff);
}
/*
@@ -1128,7 +1159,8 @@ nvm_word(size_t pos16, size_t p)
check_nvm_bound(pos16, p);
pos = (pos16 << 1) + (p * GBE_PART_SIZE);
- return (uint16_t)buf[pos] | (uint16_t)(buf[pos + 1] << 8);
+ return (uint16_t)buf[pos] |
+ ((uint16_t)buf[pos + 1] << 8);
}
static void
@@ -1182,7 +1214,7 @@ write_gbe_file_part(size_t p)
size_t gbe_rw_size;
if (gbe_fd == -1)
- err(ECANCELED, "Trying to write bad gbe_fd: %s", fname);
+ err(ECANCELED, "%s: Trying to write bad gbe_fd", fname);
gbe_rw_size = command[cmd_index].rw_size;
@@ -1192,22 +1224,22 @@ write_gbe_file_part(size_t p)
if (rval == (ssize_t)gbe_rw_size) {
errno = 0;
- printf("Wrote %zu bytes to part %zu: %s\n",
- gbe_rw_size, p, fname);
+ printf("%s: Wrote %zu bytes to part %zu\n",
+ fname, gbe_rw_size, p);
return;
}
if (rval != -1)
err(ECANCELED,
- "Short pwrite, %zd bytes, on file: %s",
- rval, fname);
+ "%s: Short pwrite, %zd bytes",
+ fname, rval);
if (errno != EINTR)
err(ECANCELED,
- "Could not pwrite file: '%s'", fname);
+ "%s: pwrite failed on p%zu", fname, p);
}
- err(EINTR, "pwrite: max retries exceeded on file: %s", fname);
+ err(EINTR, "%s: pwrite: max retries exceeded on p%zu", fname, p);
}
/*
@@ -1252,12 +1284,12 @@ gbe_x_offset(size_t p, const char *f_op, const char *d_type,
off = (off_t)p * nsize;
if (off + GBE_PART_SIZE > ncmp)
- err(ECANCELED, "GbE %s %s out of bounds: %s",
- d_type, f_op, fname);
+ err(ECANCELED, "%s: GbE %s %s out of bounds",
+ fname, d_type, f_op);
if (off != 0 && off != ncmp >> 1)
- err(ECANCELED, "GbE %s %s at bad offset: %s",
- d_type, f_op, fname);
+ err(ECANCELED, "%s: GbE %s %s at bad offset",
+ fname, d_type, f_op);
return off;
}
@@ -1288,13 +1320,15 @@ close_files(void)
{
if (gbe_fd > -1) {
if (close(gbe_fd) == -1)
- err(-1, "close '%s'", fname);
+ err(-1, "%s: close failed", fname);
+ gbe_fd = -1;
}
#ifndef NVMUTIL_ARC4RANDOM_BUF
if (urandom_fd > -1) {
if (close(urandom_fd) == -1)
- err(-1, "close '%s'", rname);
+ err(-1, "%s: close failed", rname);
+ urandom_fd = -1;
}
#endif
}