summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLeah Rowe <leah@libreboot.org>2026-03-22 19:49:50 +0000
committerLeah Rowe <leah@libreboot.org>2026-03-22 20:01:11 +0000
commita505cb261a22194c9c7f4f1a3426d3ce45a3bdf2 (patch)
tree49c19d4d1ebaebd2946c5300aef9b8279c354166
parentb8ababa2beb1b5466b6ba2062e52be36a73d654e (diff)
WIP: remove local mode in mkhtemp + cleanup
bloat unveil can get pledged Signed-off-by: Leah Rowe <leah@libreboot.org>
-rw-r--r--util/nvmutil/include/common.h5
-rw-r--r--util/nvmutil/lib/file.c140
-rw-r--r--util/nvmutil/lib/state.c13
3 files changed, 33 insertions, 125 deletions
diff --git a/util/nvmutil/include/common.h b/util/nvmutil/include/common.h
index d433197d..930150df 100644
--- a/util/nvmutil/include/common.h
+++ b/util/nvmutil/include/common.h
@@ -2,6 +2,7 @@
* Copyright (c) 2022-2026 Leah Rowe <leah@libreboot.org>
*/
+
#ifndef COMMON_H
#define COMMON_H
@@ -477,8 +478,8 @@ const char *getnvmprogname(void);
/* libc hardening
*/
-char *new_tmpfile(int *fd, int local, const char *path);
-char *new_tmplate(int *fd, int local, const char *path);
+char *new_tmpfile(int *fd);
+char *new_tmplate(int *fd);
int mkhtemp(int *fd, struct stat *st,
char *template, int dirfd, const char *fname,
struct stat *st_dir_initial);
diff --git a/util/nvmutil/lib/file.c b/util/nvmutil/lib/file.c
index 14ece22a..f6519c85 100644
--- a/util/nvmutil/lib/file.c
+++ b/util/nvmutil/lib/file.c
@@ -4,6 +4,11 @@
* Pathless i/o
*/
+#if defined(__linux__) && !defined(_GNU_SOURCE)
+/* for openat2 syscall on linux */
+#define _GNU_SOURCE 1
+#endif
+
#include <sys/types.h>
#include <sys/stat.h>
@@ -227,31 +232,20 @@ err_fsync_dir:
}
/* hardened tmpfile creation
- *
- * if not local, a standard world
- * writeable directory (e.g. /tmp)
- * will be used. otherwise,
- * the path is simply suffixed for
- * local tmp file (no world check)
- *
- * sets a file descriptor by pointer
- * fd, and returns the path as a
- * string (for your new tmp file)
- *
- * on error, the descriptor will be
- * set to -1 and errno will be set,
- * to indicate the error, and then
- * a NULL pointer will be returned.
*/
char *
-new_tmpfile(int *fd, int local,
- const char *path)
+new_tmpfile(int *fd)
{
/* TODO:
* directory support (currently only files)
*/
- size_t maxlen;
+#if defined(PATH_LEN) && \
+ (PATH_LEN) >= 256
+ size_t maxlen = PATH_LEN;
+#else
+ size_t maxlen = 4096;
+#endif
struct stat st;
char suffix[] =
@@ -262,11 +256,8 @@ new_tmpfile(int *fd, int local,
size_t pathlen;
size_t destlen;
size_t baselen;
-
char *dest = NULL; /* final path */
-
int saved_errno = errno;
-
int dirfd = -1;
const char *fname = NULL;
@@ -276,7 +267,6 @@ new_tmpfile(int *fd, int local,
* attack mitigation
*/
struct stat st_dir_initial;
-
char *dir = NULL;
char *base = NULL;
@@ -302,63 +292,24 @@ new_tmpfile(int *fd, int local,
*/
*fd = -1;
-#if defined(PATH_LEN) && \
- (PATH_LEN) >= 256
-
- maxlen = PATH_LEN;
-#else
- maxlen = 4096;
-#endif
-
/* base dir e.g. /tmp
*/
- if (!local) {
#if defined(PERMIT_NON_STICKY_ALWAYS) && \
((PERMIT_NON_STICKY_ALWAYS) > 0)
- tmpdir = env_tmpdir(PERMIT_NON_STICKY_ALWAYS);
+ tmpdir = env_tmpdir(PERMIT_NON_STICKY_ALWAYS);
#else
- tmpdir = env_tmpdir(0);
+ tmpdir = env_tmpdir(0);
#endif
- if (tmpdir == NULL)
- goto err_new_tmpfile;
- }
-
- /* local means we want
- * e.g. hello.txt to then
- * have a tmpfile created
- * for it. useful for
- * atomic writes
- */
- if (local) {
-
- if (path == NULL) {
- errno = EFAULT;
- goto err_new_tmpfile;
- }
- if (*path == '\0') {
- errno = EINVAL;
- goto err_new_tmpfile;
- }
-
- if (slen(path, maxlen, &pathlen) < 0)
- goto err_new_tmpfile;
-
- if (path[pathlen - 1] == '/') {
- errno = EINVAL;
- goto err_new_tmpfile;
- }
+ if (tmpdir == NULL)
+ goto err_new_tmpfile;
- dirlen = 0;
- } else {
+ if (slen(tmpdir, maxlen, &dirlen) < 0)
+ goto err_new_tmpfile;
- if (slen(tmpdir, maxlen, &dirlen) < 0)
- goto err_new_tmpfile;
-
- pathlen = 0;
- }
+ pathlen = 0;
/* now we want the base dir,
* with the file appended,
@@ -394,51 +345,17 @@ new_tmpfile(int *fd, int local,
goto err_new_tmpfile; /* pre-emptive fix */
}
- if (local) {
-
- if (fs_dirname_basename(path, &dir, &base, 0) < 0)
- goto err_new_tmpfile;
-
- if (slen(base, maxlen, &baselen) < 0)
- goto err_new_tmpfile;
-
- /* ALWAYS set this right after
- * split path, to avoid leaking fd:
- */
-
- dirfd = fs_open(dir, O_RDONLY | O_DIRECTORY);
- if (dirfd < 0)
- goto err_new_tmpfile;
-
- *(dest) = '.';
+ *(dest + dirlen) = '/';
+ memcpy(dest, tmpdir, dirlen);
+ memcpy(dest + dirlen + 1, suffix,
+ sizeof(suffix) - 1);
- memcpy(dest + 1, base, baselen);
-
- memcpy(dest + 1 + baselen,
- suffix, sizeof(suffix) - 1);
-
- fname = base;
-
- } else {
-
- memcpy(dest, tmpdir, dirlen);
-
- *(dest + dirlen) = '/';
-
- memcpy(dest + dirlen + 1, suffix,
- sizeof(suffix) - 1);
-
- dirfd = fs_open(tmpdir,
- O_RDONLY | O_DIRECTORY);
- if (dirfd < 0)
- goto err_new_tmpfile;
-
- /* we will use this later, throughout,
- * for detecting **directory replacement**
- */
+ dirfd = fs_open(tmpdir,
+ O_RDONLY | O_DIRECTORY);
+ if (dirfd < 0)
+ goto err_new_tmpfile;
- fname = dest + dirlen + 1;
- }
+ fname = dest + dirlen + 1;
if (fstat(dirfd, &st_dir_initial) < 0)
goto err_new_tmpfile;
@@ -446,7 +363,6 @@ new_tmpfile(int *fd, int local,
*(dest + destlen) = '\0';
*fd = mkhtemp(fd, &st, dest, dirfd, fname, &st_dir_initial);
-
if (*fd < 0)
goto err_new_tmpfile;
diff --git a/util/nvmutil/lib/state.c b/util/nvmutil/lib/state.c
index 9869bb14..836c6bc7 100644
--- a/util/nvmutil/lib/state.c
+++ b/util/nvmutil/lib/state.c
@@ -89,8 +89,6 @@ xstart(int argc, char *argv[])
};
- struct xstate *x = &us;
-
if (!first_run) {
if (pre_init)
err_no_cleanup(ECANCELED,
@@ -114,17 +112,10 @@ xstart(int argc, char *argv[])
us.argv0 = argv[0];
us.f.fname = argv[1];
-#if defined(__OpenBSD__) && defined(OpenBSD) && \
- (OpenBSD) >= 604
- /* can only use local tmp on openbsd, due to unveil */
- us.f.tname = new_tmpfile(&us.f.tmp_fd, 1, NULL);
-#else
- // TODO: new_tmplate (do for above too)
- us.f.tname = new_tmpfile(&us.f.tmp_fd, 0, NULL); // TODO: NULL BAD!
-#endif
+ us.f.tname = new_tmpfile(&us.f.tmp_fd);
/* parse user command */
-// TODO: CHECK ACCESSES VIA xstatus()
+/* TODO: CHECK ACCESSES VIA xstatus() */
set_cmd(argc, argv);
set_cmd_args(argc, argv);