diff options
| -rw-r--r-- | .gitignore | 2 | ||||
| -rw-r--r-- | util/nvmutil/.gitignore | 3 | ||||
| -rw-r--r-- | util/nvmutil/ChangeLog.md | 8 | ||||
| -rw-r--r-- | util/nvmutil/Makefile | 2 | ||||
| -rw-r--r-- | util/nvmutil/README.md | 4 | ||||
| -rw-r--r-- | util/nvmutil/nvmutil.c | 122 |
6 files changed, 82 insertions, 59 deletions
@@ -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 } |
