mirror of
https://codeberg.org/libreboot/lbmk.git
synced 2026-03-25 13:29:03 +02:00
WIP: remove local mode in mkhtemp + cleanup
bloat unveil can get pledged Signed-off-by: Leah Rowe <leah@libreboot.org>
This commit is contained in:
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
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(tmpdir, maxlen, &dirlen) < 0)
|
||||
goto err_new_tmpfile;
|
||||
|
||||
if (slen(path, maxlen, &pathlen) < 0)
|
||||
goto err_new_tmpfile;
|
||||
|
||||
if (path[pathlen - 1] == '/') {
|
||||
errno = EINVAL;
|
||||
goto err_new_tmpfile;
|
||||
}
|
||||
|
||||
dirlen = 0;
|
||||
|
||||
} else {
|
||||
|
||||
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) {
|
||||
*(dest + dirlen) = '/';
|
||||
memcpy(dest, tmpdir, dirlen);
|
||||
memcpy(dest + dirlen + 1, suffix,
|
||||
sizeof(suffix) - 1);
|
||||
|
||||
if (fs_dirname_basename(path, &dir, &base, 0) < 0)
|
||||
goto err_new_tmpfile;
|
||||
dirfd = fs_open(tmpdir,
|
||||
O_RDONLY | O_DIRECTORY);
|
||||
if (dirfd < 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) = '.';
|
||||
|
||||
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**
|
||||
*/
|
||||
|
||||
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;
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user