summaryrefslogtreecommitdiff
path: root/util/libreboot-utils
diff options
context:
space:
mode:
authorLeah Rowe <leah@libreboot.org>2026-03-24 07:41:45 +0000
committerLeah Rowe <leah@libreboot.org>2026-03-24 09:48:34 +0000
commitcce396a1ac3786b18f2c21d80c4e65e19481510d (patch)
tree0c6aea100e4254cd190640460ddaa39ce120a497 /util/libreboot-utils
parente7ede0c75570ddd57b9d55e33764c3bdd74274b1 (diff)
libreboot-utils: general code cleanup
Signed-off-by: Leah Rowe <leah@libreboot.org>
Diffstat (limited to 'util/libreboot-utils')
-rw-r--r--util/libreboot-utils/include/common.h4
-rw-r--r--util/libreboot-utils/lib/file.c349
-rw-r--r--util/libreboot-utils/lib/io.c32
-rw-r--r--util/libreboot-utils/lib/mkhtemp.c297
-rw-r--r--util/libreboot-utils/lib/num.c9
-rw-r--r--util/libreboot-utils/lib/state.c23
-rw-r--r--util/libreboot-utils/nvmutil.c5
7 files changed, 211 insertions, 508 deletions
diff --git a/util/libreboot-utils/include/common.h b/util/libreboot-utils/include/common.h
index bdd625f8..b26448db 100644
--- a/util/libreboot-utils/include/common.h
+++ b/util/libreboot-utils/include/common.h
@@ -531,6 +531,8 @@ int fs_rename_at(int olddirfd, const char *old,
int newdirfd, const char *new);
int fs_open(const char *path, int flags);
void close_no_err(int *fd);
+void free_if_null(char **buf);
+int close_warn(int *fd, char *s);
struct filesystem *rootfs(void);
int fs_resolve_at(int dirfd, const char *path, int flags);
int fs_next_component(const char **p,
@@ -543,6 +545,8 @@ int openat2p(int dirfd, const char *path,
int flags, mode_t mode);
int mkdirat_on_eintr(int dirfd,
const char *pathname, mode_t mode);
+int if_err(int condition, int errval);
+int if_err_sys(int condition);
/* asserts */
diff --git a/util/libreboot-utils/lib/file.c b/util/libreboot-utils/lib/file.c
index 00cab2e9..c9ec8f61 100644
--- a/util/libreboot-utils/lib/file.c
+++ b/util/libreboot-utils/lib/file.c
@@ -1,11 +1,12 @@
/* SPDX-License-Identifier: MIT
* Copyright (c) 2026 Leah Rowe <leah@libreboot.org>
*
- * Pathless i/o, and some stuff you probably never saw.
+ * Pathless i/o, and some stuff you
+ * probably never saw in userspace.
+ *
* Be nice to the demon.
*/
-
#include <sys/types.h>
#include <sys/stat.h>
@@ -134,32 +135,14 @@ fsync_dir(const char *path)
maxlen = 4096;
#endif
- if (path == NULL) {
- errno = EFAULT;
- goto err_fsync_dir;
- }
-
- if (slen(path, maxlen, &pathlen) < 0)
+ if (if_err(path == NULL, EFAULT) ||
+ if_err_sys(slen(path, maxlen, &pathlen) < 0) ||
+ if_err(pathlen >= maxlen || pathlen < 0, EMSGSIZE) ||
+ if_err(pathlen == 0, EINVAL)
+ ||
+ if_err_sys((dirbuf = malloc(pathlen + 1)) == NULL))
goto err_fsync_dir;
- if (pathlen >= maxlen || pathlen < 0) {
- errno = EMSGSIZE;
- goto err_fsync_dir;
- }
-
- if (pathlen == 0)
- {
- errno = EINVAL;
- goto err_fsync_dir;
- }
-
- dirbuf = malloc(pathlen + 1);
- if (dirbuf == NULL) {
-
- errno = ENOMEM;
- goto err_fsync_dir;
- }
-
memcpy(dirbuf, path, pathlen + 1);
slash = strrchr(dirbuf, '/');
@@ -183,20 +166,12 @@ fsync_dir(const char *path)
| O_NOFOLLOW
#endif
);
- if (dirfd < 0)
- goto err_fsync_dir;
-
- if (fstat(dirfd, &st) < 0)
- goto err_fsync_dir;
-
- if (!S_ISDIR(st.st_mode)) {
- errno = ENOTDIR;
- goto err_fsync_dir;
- }
-
- /* sync file on disk */
- if (fsync_on_eintr(dirfd) == -1)
+ if (if_err_sys(dirfd < 0) ||
+ if_err_sys(fstat(dirfd, &st) < 0) ||
+ if_err(!S_ISDIR(st.st_mode), ENOTDIR)
+ ||
+ if_err_sys(fsync_on_eintr(dirfd) == -1))
goto err_fsync_dir;
if (close_on_eintr(dirfd) == -1) {
@@ -205,13 +180,7 @@ fsync_dir(const char *path)
goto err_fsync_dir;
}
- if (dirbuf != NULL) {
-
- free(dirbuf);
- dirbuf = NULL;
- }
-
- dirbuf = NULL;
+ free_if_null(&dirbuf);
errno = saved_errno;
return 0;
@@ -221,19 +190,8 @@ err_fsync_dir:
if (errno == saved_errno)
errno = EIO;
- if (dirbuf != NULL) {
-
- free(dirbuf);
- dirbuf = NULL;
- }
-
- if (dirfd >= 0) {
-
- close_errno = errno;
- (void) close_on_eintr(dirfd);
- errno = close_errno;
- dirfd = -1;
- }
+ free_if_null(&dirbuf);
+ close_no_err(&dirfd);
return -1;
}
@@ -545,57 +503,19 @@ io_args(int fd, void *mem, size_t nrw,
{
int saved_errno = errno;
- /* obviously */
- if (mem == NULL) {
-
- errno = EFAULT;
- goto err_io_args;
- }
-
- /* uninitialised fd */
- if (fd < 0) {
-
- errno = EBADF;
+ if (if_err(mem == NULL, EFAULT) ||
+ if_err(fd < 0, EBADF) ||
+ if_err(off < 0, ERANGE) ||
+ if_err(!nrw, EPERM) || /* TODO: toggle zero-byte check */
+ if_err(nrw > (size_t)SSIZE_MAX, ERANGE) ||
+ if_err(((size_t)off + nrw) < (size_t)off, ERANGE) ||
+ if_err(rw_type > IO_PWRITE, EINVAL))
goto err_io_args;
- }
-
- /* negative offset */
- if (off < 0) {
-
- errno = ERANGE;
- goto err_io_args;
- }
-
- /* prevent zero-byte rw */
- if (!nrw)
- goto err_io_args;
-
- /* prevent overflow */
- if (nrw > (size_t)SSIZE_MAX) {
-
- errno = ERANGE;
- goto err_io_args;
- }
-
- /* prevent overflow */
- if (((size_t)off + nrw) < (size_t)off) {
-
- errno = ERANGE;
- goto err_io_args;
- }
-
- if (rw_type > IO_PWRITE) {
-
- errno = EINVAL;
- goto err_io_args;
- }
errno = saved_errno;
-
return 0;
err_io_args:
-
if (errno == saved_errno)
errno = EINVAL;
@@ -607,31 +527,16 @@ check_file(int fd, struct stat *st)
{
int saved_errno = errno;
- if (fd < 0) {
- errno = EBADF;
- goto err_is_file;
- }
-
- if (st == NULL) {
- errno = EFAULT;
- goto err_is_file;
- }
-
- if (fstat(fd, st) == -1)
- goto err_is_file;
-
- if (!S_ISREG(st->st_mode)) {
-
- errno = EBADF;
+ if (if_err(fd < 0, EBADF) ||
+ if_err(st == NULL, EFAULT) ||
+ if_err(fstat(fd, st) == -1, 0) ||
+ if_err(!S_ISREG(st->st_mode), EBADF))
goto err_is_file;
- }
errno = saved_errno;
-
return 0;
err_is_file:
-
if (errno == saved_errno)
errno = EINVAL;
@@ -647,54 +552,16 @@ rw_over_nrw(ssize_t r, size_t nrw)
{
int saved_errno = errno;
- /* not a libc bug, but we
- * don't like the number zero
- */
- if (!nrw)
- goto err_rw_over_nrw;
-
- if (r == -1)
- return r;
-
- if ((size_t)
- r > SSIZE_MAX) {
-
- /* Theoretical buggy libc
- * check. Extremely academic.
- *
- * Specifications never
- * allow this return value
- * to exceed SSIZE_T, but
- * spec != implementation
- *
- * Check this after using
- * [p]read() or [p]write()
- *
- * NOTE: here, we assume
- * ssize_t integers are the
- * same size as SSIZE_T
- */
-
- errno = ERANGE;
+ if (if_err(!nrw, 0) ||
+ if_err(r == -1, 0) ||
+ if_err((size_t)r > SSIZE_MAX, ERANGE) ||
+ if_err((size_t)r > nrw, ERANGE))
goto err_rw_over_nrw;
- }
-
- /* Theoretical buggy libc:
- * Should never return a number of
- * bytes above the requested length.
- */
- if ((size_t)r > nrw) {
-
- errno = ERANGE;
- goto err_rw_over_nrw;
- }
errno = saved_errno;
-
return r;
err_rw_over_nrw:
-
if (errno == saved_errno)
errno = EIO;
@@ -723,23 +590,91 @@ lseek_on_eintr(int fd, off_t off, int whence,
}
#endif
+/* two functions that reduce sloccount by
+ * two hundred lines... no, now three. */
+int
+if_err(int condition, int errval)
+{
+ if (!condition)
+ return 0;
+
+ if (errval)
+ errno = errval;
+
+ return 1;
+}
+/* technically pointless, but stylistically
+ * pleasing alongside if_err chains.
+ * use this one for syscalls that are
+ * expected to set errno
+ * also use it for non-system calls
+ * that act like them, e.g. prw() or
+ * rw_write_exact() */
+int
+if_err_sys(int condition)
+{
+ if (!condition)
+ return 0;
+ return 1;
+}
+/* errno can never be -1, so you can
+ * use this to conditionally set an integer
+ * for comparison. see example in lseek_on_eintr
+ */
int
try_err(int loop_err, int errval)
{
if (loop_err)
return errval;
-
return -1;
}
void
+free_if_null(char **buf)
+{
+ if (buf == NULL || *buf == NULL)
+ return;
+
+ free(*buf);
+ *buf = NULL;
+}
+
+/* also returns error code */
+int
+close_warn(int *fd, char *s)
+{
+ int saved_errno = errno;
+
+ if (fd == NULL) {
+ if (s != NULL)
+ fprintf(stderr, "FAIL: %s: bad fd ptr\n", s);
+ return -1;
+ }
+
+ if (*fd < 0 && s != NULL) {
+ fprintf(stderr, "WARN: %s: already closed\n", s);
+ } else if (close(*fd) < 0) {
+ if (s != NULL)
+ fprintf(stderr, "FAIL: %s: close\n", s);
+ return -1;
+ }
+
+ *fd = -1;
+ errno = saved_errno;
+
+ return 0;
+}
+
+/* TODO: remove this. giant liability.
+ make close calls always err instead,
+ when they fail. otherwise we hide bugs!
+ */
+void
close_no_err(int *fd)
{
int saved_errno = errno;
- if (fd == NULL)
- return;
- if (*fd < 0)
+ if (fd == NULL || *fd < 0)
return;
(void) close_on_eintr(*fd);
@@ -748,6 +683,9 @@ close_no_err(int *fd)
errno = saved_errno;
}
+/* TODO: make fd a pointer insttead
+ and automatically reset -1 here */
+/* BUT DO NOT reset -1 on error */
int
close_on_eintr(int fd)
{
@@ -787,17 +725,9 @@ int
fs_rename_at(int olddirfd, const char *old,
int newdirfd, const char *new)
{
- if (new == NULL || old == NULL) {
-
- errno = EFAULT;
+ if (if_err(new == NULL || old == NULL, EFAULT) ||
+ if_err(olddirfd < 0 || newdirfd < 0, EBADF))
return -1;
- }
-
- if (olddirfd < 0 || newdirfd < 0) {
-
- errno = EBADF;
- return -1;
- }
return renameat(olddirfd, old, newdirfd, new);
}
@@ -812,25 +742,13 @@ int
fs_open(const char *path, int flags)
{
struct filesystem *fs;
- const char *rel;
-
- if (path == NULL) {
- errno = EFAULT;
- return -1;
- }
-
- if (path[0] != '/') {
- errno = EINVAL;
- return -1;
- }
- fs = rootfs();
- if (fs == NULL)
+ if (if_err(path == NULL, EFAULT) ||
+ if_err(path[0] != '/', EINVAL) ||
+ if_err_sys((fs = rootfs()) == NULL))
return -1;
- rel = path + 1;
-
- return fs_resolve_at(fs->rootfd, rel, flags);
+ return fs_resolve_at(fs->rootfd, path + 1, flags);
}
/* singleton function
@@ -980,12 +898,8 @@ fs_open_component(int dirfd, const char *name,
*/
if (!is_last) {
- if (fd < 0) {
- errno = EBADF;
- return -1;
- }
-
- if (fstat(fd, &st) < 0)
+ if (if_err(fd < 0, EBADF) ||
+ if_err_sys(fstat(fd, &st) < 0))
return -1;
if (!S_ISDIR(st.st_mode)) {
@@ -1015,14 +929,9 @@ fs_dirname_basename(const char *path,
size_t maxlen = 4096;
#endif
- if (path == NULL || dir == NULL || base == NULL)
- return -1;
-
- if (slen(path, maxlen, &len) < 0)
- return -1;
-
- buf = malloc(len + 1);
- if (buf == NULL)
+ if (path == NULL || dir == NULL || base == NULL ||
+ if_err_sys(slen(path, maxlen, &len) < 0) ||
+ if_err_sys((buf = malloc(len + 1)) == NULL))
return -1;
memcpy(buf, path, len + 1);
@@ -1049,7 +958,7 @@ fs_dirname_basename(const char *path,
*base = buf;
} else {
errno = EINVAL;
- free(buf);
+ free_if_null(&buf);
return -1;
}
@@ -1079,15 +988,9 @@ openat2p(int dirfd, const char *path,
int rval;
#endif
- if (dirfd < 0) {
- errno = EBADF;
- return -1;
- }
-
- if (path == NULL) {
- errno = EFAULT;
+ if (if_err(dirfd < 0, EBADF) ||
+ if_err(path == NULL, EFAULT))
return -1;
- }
retry:
errno = 0;
@@ -1124,15 +1027,9 @@ mkdirat_on_eintr( /* <-- say that 10 times to please the demon */
int saved_errno = errno;
int rval;
- if (dirfd < 0) {
- errno = EBADF;
- return -1;
- }
-
- if (path == NULL) {
- errno = EFAULT;
+ if (if_err(dirfd < 0, EBADF) ||
+ if_err(path == NULL, EFAULT))
return -1;
- }
retry:
errno = 0;
diff --git a/util/libreboot-utils/lib/io.c b/util/libreboot-utils/lib/io.c
index 94bde87e..cc38e5c7 100644
--- a/util/libreboot-utils/lib/io.c
+++ b/util/libreboot-utils/lib/io.c
@@ -239,21 +239,8 @@ write_to_gbe_bin(void)
saved_errno = errno;
- if (close_on_eintr(f->tmp_fd) == -1) {
- f->tmp_fd = -1;
-
- fprintf(stderr, "FAIL: %s: close\n", f->tname);
- f->io_err_gbe_bin = 1;
- }
- f->tmp_fd = -1;
-
- if (close_on_eintr(f->gbe_fd) == -1) {
- f->gbe_fd = -1;
-
- fprintf(stderr, "FAIL: %s: close\n", f->fname);
- f->io_err_gbe_bin = 1;
- }
- f->gbe_fd = -1;
+ f->io_err_gbe_bin |= -close_warn(&f->tmp_fd, f->tname);
+ f->io_err_gbe_bin |= -close_warn(&f->gbe_fd, f->fname);
errno = saved_errno;
@@ -279,13 +266,7 @@ write_to_gbe_bin(void)
/* removed by rename
*/
-
- if (f->tname != NULL) {
- free(f->tname);
- f->tname = NULL;
- }
-
- f->tname = NULL;
+ free_if_null(&f->tname);
}
}
@@ -513,12 +494,7 @@ gbe_mv(void)
goto ret_gbe_mv;
}
- if (dest_tmp != NULL) {
- free(dest_tmp);
- dest_tmp = NULL;
- }
-
- dest_tmp = NULL;
+ free_if_null(&dest_tmp);
ret_gbe_mv:
diff --git a/util/libreboot-utils/lib/mkhtemp.c b/util/libreboot-utils/lib/mkhtemp.c
index 8f54b045..b30f6587 100644
--- a/util/libreboot-utils/lib/mkhtemp.c
+++ b/util/libreboot-utils/lib/mkhtemp.c
@@ -168,10 +168,7 @@ err:
else
saved_errno = errno = EIO;
- if (dest != NULL) {
- free(dest);
- dest = NULL;
- }
+ free_if_null(&dest);
close_no_err(&dirfd);
close_no_err(fd);
@@ -543,76 +540,32 @@ mkhtemp(int *fd,
int r;
char *end;
- if (fd == NULL ||
- template == NULL ||
- fname == NULL ||
- st_dir_initial == NULL) {
-
- errno = EFAULT;
- return -1;
- }
-
- /* we do not mess with an
- open descriptor.
- */
- if (*fd >= 0) {
- errno = EEXIST; /* leave their file alone */
- return -1;
- }
-
- if (dirfd < 0) {
- errno = EBADF;
- return -1;
- }
-
- if (slen(template, max_len, &len) < 0)
- return -1;
-
- if (len >= max_len) {
- errno = EMSGSIZE;
+ if (if_err(fd == NULL || template == NULL || fname == NULL ||
+ st_dir_initial == NULL, EFAULT) ||
+ if_err(*fd >= 0, EEXIST) ||
+ if_err(dirfd < 0, EBADF)
+ ||
+ if_err_sys(slen(template, max_len, &len) < 0) ||
+ if_err(len >= max_len, EMSGSIZE)
+ ||
+ if_err_sys(slen(fname, max_len, &fname_len)) ||
+ if_err(fname == 0, EINVAL) ||
+ if_err(strrchr(fname, '/') != NULL, EINVAL))
return -1;
- }
-
- if (slen(fname, max_len, &fname_len) < 0)
- return -1;
-
- if (fname_len == 0) {
- errno = EINVAL;
- return -1;
- }
-
- if (strrchr(fname, '/') != NULL) {
- errno = EINVAL;
- return -1;
- }
- /* count trailing X */
- end = template + len;
- while (end > template && *--end == 'X')
- xc++;
+ for (end = template + len; /* count X */
+ end > template && *--end == 'X'; xc++);
- if (xc < 6 || xc > len) {
- errno = EINVAL;
+ if (if_err(xc < 6 || xc > len, EINVAL) ||
+ if_err(fname_len > len, EOVERFLOW))
return -1;
- }
- if (fname_len > len) {
- errno = EOVERFLOW;
+ if (if_err(memcmp(fname, template + len - fname_len,
+ fname_len) != 0, EINVAL))
return -1;
- }
- if (memcmp(fname,
- template + len - fname_len,
- fname_len) != 0) {
- errno = EINVAL;
- return -1;
- }
-
- fname_copy = malloc(fname_len + 1);
- if (fname_copy == NULL) {
- errno = ENOMEM;
+ if((fname_copy = malloc(fname_len + 1)) == NULL)
goto err;
- }
/* fname_copy = suffix region only; p points to trailing XXXXXX */
memcpy(fname_copy,
@@ -622,15 +575,9 @@ mkhtemp(int *fd,
for (retries = 0; retries < MKHTEMP_RETRY_MAX; retries++) {
- r = mkhtemp_try_create(
- dirfd,
- st_dir_initial,
- fname_copy,
- p,
- xc,
- fd,
- st,
- type);
+ r = mkhtemp_try_create(dirfd,
+ st_dir_initial, fname_copy,
+ p, xc, fd, st, type);
if (r == 0) {
if (retries >= MKHTEMP_SPIN_THRESHOLD) {
@@ -658,9 +605,7 @@ err:
close_no_err(fd);
success:
-
- if (fname_copy != NULL)
- free(fname_copy);
+ free_if_null(&fname_copy);
return (*fd >= 0) ? *fd : -1;
}
@@ -682,29 +627,21 @@ mkhtemp_try_create(int dirfd,
int file_created = 0;
int dir_created = 0;
- if (fd == NULL || st == NULL || p == NULL || fname_copy == NULL ||
- st_dir_initial == NULL) {
- errno = EFAULT;
- goto err;
- } else if (*fd >= 0) { /* do not mess with someone else's file */
- errno = EEXIST;
- goto err;
- }
-
- if (mkhtemp_fill_random(p, xc) < 0)
+ if (if_err(fd == NULL || st == NULL || p ==NULL || fname_copy ==NULL ||
+ st_dir_initial == NULL, EFAULT) ||
+ if_err(*fd >= 0, EEXIST))
goto err;
- if (fd_verify_dir_identity(dirfd, st_dir_initial) < 0)
+ if (if_err_sys(mkhtemp_fill_random(p, xc) < 0) ||
+ if_err_sys(fd_verify_dir_identity(dirfd, st_dir_initial) < 0))
goto err;
if (type == MKHTEMP_FILE) {
*fd = openat2p(dirfd, fname_copy,
O_RDWR | O_CREAT | O_EXCL |
- O_NOFOLLOW | O_CLOEXEC | O_NOCTTY,
- 0600);
+ O_NOFOLLOW | O_CLOEXEC | O_NOCTTY, 0600);
- /* O_CREAT and O_EXCL guarantees
- * creation upon success
+ /* O_CREAT and O_EXCL guarantees creation upon success
*/
if (*fd >= 0)
file_created = 1;
@@ -724,23 +661,15 @@ mkhtemp_try_create(int dirfd,
if (fd_verify_dir_identity(dirfd, st_dir_initial) < 0)
goto err;
- *fd = openat2p(dirfd, fname_copy,
- O_RDONLY | O_DIRECTORY | O_CLOEXEC, 0);
- if (*fd < 0)
+ if ((*fd = openat2p(dirfd, fname_copy,
+ O_RDONLY | O_DIRECTORY | O_CLOEXEC, 0)) < 0)
goto err;
- if (fstat(*fd, &st_open) < 0)
+ if (if_err_sys(fstat(*fd, &st_open) < 0) ||
+ if_err(!S_ISDIR(st_open.st_mode), ENOTDIR))
goto err;
- if (!S_ISDIR(st_open.st_mode)) {
- errno = ENOTDIR;
- goto err;
- }
-
- /* NOTE: could check nlink count here,
- * but it's not very reliable here. skipped.
- */
-
+ /* NOTE: pointless to check nlink here (only just opened) */
if (fd_verify_dir_identity(dirfd, st_dir_initial) < 0)
goto err;
@@ -776,19 +705,10 @@ mkhtemp_try_create(int dirfd,
if (fd_verify_identity(*fd, &st_open, st_dir_initial) < 0)
goto err;
- if (!S_ISDIR(st_open.st_mode)) {
- errno = ENOTDIR;
- goto err;
- }
-
- if (is_owner(&st_open) < 0)
- goto err;
-
- /* group/world writeable */
- if (st_open.st_mode & (S_IWGRP | S_IWOTH)) {
- errno = EPERM;
+ if (if_err(!S_ISDIR(st_open.st_mode), ENOTDIR) ||
+ if_err_sys(is_owner(&st_open) < 0) ||
+ if_err(st_open.st_mode & (S_IWGRP | S_IWOTH), EPERM))
goto err;
- }
}
errno = saved_errno;
@@ -800,7 +720,6 @@ err:
if (file_created)
(void) unlinkat(dirfd, fname_copy, 0);
-
if (dir_created)
(void) unlinkat(dirfd, fname_copy, AT_REMOVEDIR);
@@ -879,6 +798,9 @@ err_mkhtemp_fill_random:
* !!! DO NOT RUN TWICE PER FILE. BEWARE OF THE DEMON !!!
* watch out for spikes!
*/
+/* TODO: bad_flags can be negative, and is
+ * ignored if it is. should we err instead?
+ */
int secure_file(int *fd,
struct stat *st,
struct stat *expected,
@@ -890,93 +812,40 @@ int secure_file(int *fd,
int flags;
struct stat st_now;
int saved_errno = errno;
- /* you have been warned */
- if (fd == NULL) {
- errno = EFAULT;
- goto err_demons;
- }
- if (*fd < 0) {
- errno = EBADF;
- goto err_demons;
- }
-
- if (st == NULL) {
- errno = EFAULT;
- goto err_demons;
- }
-
- flags = fcntl(*fd, F_GETFL);
- if (flags == -1)
+ if (if_err(fd == NULL || st == NULL, EFAULT) ||
+ if_err(*fd < 0, EBADF) ||
+ if_err_sys((flags = fcntl(*fd, F_GETFL)) == -1) ||
+ if_err(bad_flags > 0 && (flags & bad_flags), EPERM))
goto err_demons;
- if (bad_flags > 0) {
-
- /* e.g. O_APPEND breaks pwrite/pread
- * by allowing offsets to be ignored */
- if (flags & bad_flags) {
- errno = EPERM;
- goto err_demons;
- }
- }
-
if (expected != NULL) {
if (fd_verify_regular(*fd, expected, st) < 0)
goto err_demons;
- } else {
- if (fstat(*fd, &st_now) == -1)
- goto err_demons;
-
- if (!S_ISREG(st_now.st_mode)) {
- errno = EBADF;
- goto err_demons;
- }
-
- *st = st_now;
- }
-
- if (check_seek) {
-
- /* check if it's seekable */
+ } else if (if_err_sys(fstat(*fd, &st_now) == -1) ||
+ if_err(!S_ISREG(st_now.st_mode), EBADF)) {
+ goto err_demons; /***********/
+ } else /* ( >:3 ) */
+ *st = st_now; /* /| |\ */ /* don't let him out */
+ /* / \ */
+ if (check_seek) { /***********/
if (lseek(*fd, 0, SEEK_CUR) == (off_t)-1)
goto err_demons;
- }
-
- /* don't release the demon
- */
- if (st->st_nlink != 1) { /***********/
- /* ( >:3 ) */
- errno = ELOOP; /* /| |\ */ /* don't let him out */
- goto err_demons; /* / \ */
- /***********/
- }
-
- if (st->st_uid != geteuid() && /* someone else's file */
- geteuid() != 0) { /* override for root */
+ } /* don't release the demon */
- errno = EPERM;
- goto err_demons;
- }
- if (is_owner(st) < 0)
+ if (if_err(st->st_nlink != 1, ELOOP) ||
+ if_err(st->st_uid != geteuid() && geteuid() != 0, EPERM) ||
+ if_err_sys(is_owner(st) < 0) ||
+ if_err(st->st_mode & (S_IWGRP | S_IWOTH), EPERM))
goto err_demons;
- /* world-writeable or group-ownership.
- * if these are set, then others could
- * modify the file (not secure)
- */
- if (st->st_mode & (S_IWGRP | S_IWOTH)) {
- errno = EPERM;
- goto err_demons;
- }
-
if (do_lock) {
if (lock_file(*fd, flags) == -1)
goto err_demons;
- if (expected != NULL) {
+ if (expected != NULL)
if (fd_verify_identity(*fd, expected, &st_now) < 0)
goto err_demons;
- }
}
if (fchmod(*fd, mode) == -1)
@@ -997,16 +866,12 @@ int
fd_verify_regular(int fd,
const struct stat *expected,
struct stat *out)
-{
- if (fd_verify_identity(fd, expected, out) < 0)
- return -1;
-
- if (!S_ISREG(out->st_mode)) {
- errno = EBADF;
- return -1;
- }
-
- return 0; /* regular file */
+{if (
+ if_err_sys(fd_verify_identity(fd, expected, out) < 0) ||
+ if_err(!S_ISREG(out->st_mode), EBADF)
+ ) return -1;
+ else
+ return 0; /* regular file */
}
int
@@ -1017,20 +882,12 @@ fd_verify_identity(int fd,
struct stat st_now;
int saved_errno = errno;
- if (fd < 0 || expected == NULL) {
- errno = EFAULT;
- return -1;
- }
-
- if (fstat(fd, &st_now) < 0)
+if( if_err(fd < 0 || expected == NULL, EFAULT) ||
+ if_err_sys(fstat(fd, &st_now)) ||
+ if_err(st_now.st_dev != expected->st_dev ||
+ st_now.st_ino != expected->st_ino, ESTALE))
return -1;
- if (st_now.st_dev != expected->st_dev ||
- st_now.st_ino != expected->st_ino) {
- errno = ESTALE;
- return -1;
- }
-
if (out != NULL)
*out = st_now;
@@ -1045,12 +902,8 @@ fd_verify_dir_identity(int fd,
struct stat st_now;
int saved_errno = errno;
- if (fd < 0 || expected == NULL) {
- errno = EFAULT;
- return -1;
- }
-
- if (fstat(fd, &st_now) < 0)
+ if (if_err(fd < 0 || expected == NULL, EFAULT) ||
+ if_err_sys(fstat(fd, &st_now) < 0))
return -1;
if (st_now.st_dev != expected->st_dev ||
@@ -1096,15 +949,9 @@ lock_file(int fd, int flags)
struct flock fl;
int saved_errno = errno;
- if (fd < 0) {
- errno = EBADF;
+ if (if_err(fd < 0, EBADF) ||
+ if_err(flags < 0, EINVAL))
goto err_lock_file;
- }
-
- if (flags < 0) {
- errno = EINVAL;
- goto err_lock_file;
- }
memset(&fl, 0, sizeof(fl));
diff --git a/util/libreboot-utils/lib/num.c b/util/libreboot-utils/lib/num.c
index 343350b0..91a1514f 100644
--- a/util/libreboot-utils/lib/num.c
+++ b/util/libreboot-utils/lib/num.c
@@ -257,12 +257,9 @@ retry_urandom_read:
nr = new_nr;
off = 0;
- /* to mitigate file descriptor
- * injection, we do not re-use
- * the same descriptor each time
- */
- (void) close_on_eintr(fd);
- fd = -1;
+ /* don't re-use same fd, to mitaget
+ * fd injection */
+ close_no_err(&fd);
}
fd = -1;
diff --git a/util/libreboot-utils/lib/state.c b/util/libreboot-utils/lib/state.c
index a3ad0f1e..b7701f0d 100644
--- a/util/libreboot-utils/lib/state.c
+++ b/util/libreboot-utils/lib/state.c
@@ -204,28 +204,13 @@ exit_cleanup(void)
if (x != NULL) {
f = &x->f;
- if (f->gbe_fd > -1) {
- if (close_on_eintr(f->gbe_fd) == -1) {
- f->gbe_fd = -1;
- close_err = 1;
- }
- f->gbe_fd = -1;
- }
-
- if (f->tmp_fd > -1) {
- if (close_on_eintr(f->tmp_fd) == -1) {
- f->tmp_fd = -1;
- close_err = 1;
- }
- f->tmp_fd = -1;
- }
+ close_no_err(&f->gbe_fd);
+ close_no_err(&f->tmp_fd);
+ close_no_err(&f->tmp_fd);
- if (f->tname != NULL) {
+ if (f->tname != NULL)
if (unlink(f->tname) == -1)
close_err = 1;
- }
-
- f->tmp_fd = -1;
}
if (saved_errno)
diff --git a/util/libreboot-utils/nvmutil.c b/util/libreboot-utils/nvmutil.c
index fa6384b0..fb45a97c 100644
--- a/util/libreboot-utils/nvmutil.c
+++ b/util/libreboot-utils/nvmutil.c
@@ -123,10 +123,7 @@ main(int argc, char *argv[])
if (f->io_err_gbe_bin)
err(EIO, "%s: error writing final file");
- if (f->tname != NULL) {
- free(f->tname);
- f->tname = NULL;
- }
+ free_if_null(&f->tname);
return EXIT_SUCCESS;
}