mirror of
https://codeberg.org/libreboot/lbmk.git
synced 2026-07-11 05:52:36 +02:00
d2abde5303
where possible, try not to clobber sys errno. override it only when relatively safe. also: when a syscall succeeds, it may set errno. this is rare, but permitted (nothing specified against it in specs, and the specs say that errno is undefined on success). i'm not libc, but i'm wrapping around it, so i need to be careful in how i handle the errno value. also: i removed the requirement for directories to be executable, in mkhtemp.c, because this isn't required and will only break certain setups. in world_writeable and sticky, i made the checks stricter: the faccessat check was being skipped on some paths, so i've closed that loophole now. i also generally cleaned up some code, as part of the errno handling refactoring, where it made sense to do so, plus a few other bits of code cleanup. Signed-off-by: Leah Rowe <leah@libreboot.org>
117 lines
2.4 KiB
C
117 lines
2.4 KiB
C
/* SPDX-License-Identifier: MIT ( >:3 )
|
|
* Copyright (c) 2022-2026 Leah Rowe <leah@libreboot.org> /| |\
|
|
* / \
|
|
* 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.
|
|
*/
|
|
|
|
#include <sys/types.h>
|
|
#include <sys/stat.h>
|
|
|
|
#include <errno.h>
|
|
#include <fcntl.h>
|
|
#include <limits.h>
|
|
#include <stdarg.h>
|
|
#include <stddef.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <unistd.h>
|
|
|
|
#include "include/common.h"
|
|
|
|
static void
|
|
exit_cleanup(void);
|
|
|
|
int
|
|
main(int argc, char *argv[])
|
|
{
|
|
struct xstate *x;
|
|
struct commands *cmd;
|
|
struct xfile *f;
|
|
size_t c;
|
|
|
|
(void) errhook(exit_cleanup);
|
|
(void) lbsetprogname(argv[0]);
|
|
|
|
/* https://man.openbsd.org/pledge.2 */
|
|
/* https://man.openbsd.org/unveil.2 */
|
|
xpledgex("stdio flock rpath wpath cpath unveil", NULL);
|
|
xunveilx("/dev/urandom", "r");
|
|
|
|
#ifndef S_ISREG
|
|
err_exit(ECANCELED,
|
|
"Can't determine file types (S_ISREG undefined)");
|
|
#endif
|
|
#if ((CHAR_BIT) != 8)
|
|
err_exit(ECANCELED, "Unsupported char size");
|
|
#endif
|
|
|
|
if ((x = xstart(argc, argv)) == NULL)
|
|
err_exit(ECANCELED, "NULL state on init");
|
|
|
|
/* parse user command */
|
|
/* TODO: CHECK ACCESSES VIA xstatus() */
|
|
set_cmd(argc, argv);
|
|
set_cmd_args(argc, argv);
|
|
|
|
cmd = &x->cmd[x->i];
|
|
f = &x->f;
|
|
|
|
if ((cmd->flags & O_ACCMODE) == O_RDONLY)
|
|
xunveilx(f->fname, "r");
|
|
else
|
|
xunveilx(f->fname, "rwc");
|
|
|
|
xunveilx(f->tname, "rwc");
|
|
xunveilx(NULL, NULL);
|
|
xpledgex("stdio flock rpath wpath cpath", NULL);
|
|
|
|
if (cmd->run == NULL)
|
|
err_exit(errno, "Command not set");
|
|
|
|
sanitize_command_list();
|
|
open_gbe_file();
|
|
copy_gbe();
|
|
read_checksums();
|
|
cmd->run();
|
|
|
|
for (c = 0; c < items(x->cmd); c++)
|
|
x->cmd[c].run = cmd_helper_err;
|
|
|
|
if ((cmd->flags & O_ACCMODE) == O_RDWR)
|
|
write_to_gbe_bin();
|
|
|
|
exit_cleanup();
|
|
if (f->io_err_gbe_bin)
|
|
err_exit(EIO, "%s: error writing final file");
|
|
|
|
free_and_set_null(&f->tname);
|
|
|
|
return EXIT_SUCCESS;
|
|
}
|
|
|
|
static void
|
|
exit_cleanup(void)
|
|
{
|
|
struct xstate *x;
|
|
struct xfile *f;
|
|
|
|
x = xstatus();
|
|
if (x == NULL)
|
|
return;
|
|
|
|
f = &x->f;
|
|
|
|
/* close fds if still open */
|
|
close_on_eintr(&f->tmp_fd);
|
|
close_on_eintr(&f->gbe_fd);
|
|
|
|
/* unlink tmpfile if it exists */
|
|
if (f->tname != NULL) {
|
|
(void) unlink(f->tname);
|
|
free_and_set_null(&f->tname);
|
|
}
|
|
}
|