summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--util/libreboot-utils/Makefile19
-rw-r--r--util/libreboot-utils/include/common.h35
-rw-r--r--util/libreboot-utils/lib/command.c4
-rw-r--r--util/libreboot-utils/lib/file.c214
-rw-r--r--util/libreboot-utils/lib/io.c23
-rw-r--r--util/libreboot-utils/lib/mkhtemp.c59
-rw-r--r--util/libreboot-utils/lib/rand.c61
-rw-r--r--util/libreboot-utils/lib/state.c4
-rw-r--r--util/libreboot-utils/mkhtemp.c5
-rw-r--r--util/libreboot-utils/nvmutil.c8
10 files changed, 168 insertions, 264 deletions
diff --git a/util/libreboot-utils/Makefile b/util/libreboot-utils/Makefile
index 3fa9fd0e..92e8a3a6 100644
--- a/util/libreboot-utils/Makefile
+++ b/util/libreboot-utils/Makefile
@@ -8,12 +8,18 @@
CC = cc
HELLCC = clang
-CFLAGS = -Os -Wall -Wextra -std=c99 -pedantic -Werror
+CFLAGS = -Os -Wall -Wextra -std=c99 -pedantic
LDFLAGS =
DESTDIR =
PREFIX = /usr/local
INSTALL = install
+# used for portability testing on linux:
+#
+PORT_OPENAT = -DUSE_OPENAT=1
+PORT_ARC4 = -DUSE_ARC4=1
+PORT_URANDOM = -DUSE_URANDOM=1
+
.SUFFIXES: .c .o
LDIR =
@@ -148,4 +154,13 @@ distclean: clean
# mode targets (portable replacement for ifeq)
strict:
- $(MAKE) CFLAGS="$(HELLFLAGS)" CC_MODE="$(HELLCC)"
+ $(MAKE) CFLAGS="$(CFLAGS) $(HELLFLAGS)" CC_MODE="$(HELLCC)"
+
+# BSD-like portability test (openat + arc4random)
+portable-bsd:
+ $(MAKE) CFLAGS="$(CFLAGS) $(PORT_OPENAT) $(PORT_ARC4)" CC_MODE="$(CC)"
+
+# fallback portability test (openat + urandom -- old linux mostly)
+portable-urandom:
+ $(MAKE) CFLAGS="$(CFLAGS) $(PORT_OPENAT) $(PORT_URANDOM)" \
+ CC_MODE="$(CC)"
diff --git a/util/libreboot-utils/include/common.h b/util/libreboot-utils/include/common.h
index a08dec08..7d566d70 100644
--- a/util/libreboot-utils/include/common.h
+++ b/util/libreboot-utils/include/common.h
@@ -13,18 +13,6 @@
#include <sys/types.h>
#include <sys/stat.h>
#include <limits.h>
-#include <errno.h>
-
-/* for linux getrandom
- */
-#if defined(__linux__)
-#include <sys/random.h>
-#include <sys/syscall.h>
-#endif
-
-#ifdef __OpenBSD__ /* for pledge */
-#include <unistd.h>
-#endif
/* dangerously cool macros:
*/
@@ -46,11 +34,6 @@
#define items(x) (sizeof((x)) / sizeof((x)[0]))
-/* system prototypes
- */
-
-int fchmod(int fd, mode_t mode);
-
#define MKHTEMP_RETRY_MAX 512
#define MKHTEMP_SPIN_THRESHOLD 32
@@ -100,10 +83,6 @@ int fchmod(int fd, mode_t mode);
#error "Unexpected bit layout"
#endif
-#ifndef MAX_ZERO_RW_RETRY
-#define MAX_ZERO_RW_RETRY 5
-#endif
-
#ifndef _FILE_OFFSET_BITS
#define _FILE_OFFSET_BITS 64
#endif
@@ -478,8 +457,8 @@ ssize_t rw_gbe_file_exact(int fd, unsigned char *mem, size_t nrw,
*/
int fsync_dir(const char *path);
-ssize_t rw_file_exact(int fd, unsigned char *mem, size_t len,
- off_t off, int rw_type, size_t max_retries);
+ssize_t rw_exact(int fd, unsigned char *mem, size_t len,
+ off_t off, int rw_type);
ssize_t rw(int fd, void *mem, size_t nrw,
off_t off, int rw_type);
int io_args(int fd, void *mem, size_t nrw,
@@ -488,14 +467,6 @@ int check_file(int fd, struct stat *st);
ssize_t rw_over_nrw(ssize_t r, size_t nrw);
off_t lseek_on_eintr(int fd, off_t off,
int whence);
-ssize_t read_on_eintr(int fd,
- void *buf, size_t count);
-ssize_t write_on_eintr(int fd,
- void *buf, size_t count);
-ssize_t pread_on_eintr(int fd,
- void *buf, size_t count, off_t off);
-ssize_t pwrite_on_eintr(int fd,
- void *buf, size_t count, off_t off);
int off_retry(int saved_errno, off_t rval);
int sys_retry(int saved_errno, long rval);
int fs_retry(int saved_errno, int rval);
@@ -554,7 +525,7 @@ int secure_file(int *fd,
int check_seek,
int do_lock,
mode_t mode);
-void close_on_eintr(int *fd);
+void xclose(int *fd);
int fsync_on_eintr(int fd);
int fs_rename_at(int olddirfd, const char *old,
int newdirfd, const char *new);
diff --git a/util/libreboot-utils/lib/command.c b/util/libreboot-utils/lib/command.c
index 526ad03b..3bdc4191 100644
--- a/util/libreboot-utils/lib/command.c
+++ b/util/libreboot-utils/lib/command.c
@@ -492,8 +492,8 @@ cat_buf(unsigned char *b)
if (b == NULL)
exitf("null pointer in cat command");
- if (rw_file_exact(STDOUT_FILENO, b,
- GBE_PART_SIZE, 0, IO_WRITE, MAX_ZERO_RW_RETRY) < 0)
+ if (rw_exact(STDOUT_FILENO, b,
+ GBE_PART_SIZE, 0, IO_WRITE) < 0)
exitf("stdout: cat");
}
void
diff --git a/util/libreboot-utils/lib/file.c b/util/libreboot-utils/lib/file.c
index 9c4683ce..862e82cc 100644
--- a/util/libreboot-utils/lib/file.c
+++ b/util/libreboot-utils/lib/file.c
@@ -16,9 +16,17 @@ more correct usage example:
long max = pathconf("/", _PC_PATH_MAX);
*/
+/* for openat2: */
+#ifdef __linux__
+#if !defined(USE_OPENAT) || \
+ ((USE_OPENAT) < 1) /* if 1: use openat, not openat2 */
#ifndef _GNU_SOURCE
#define _GNU_SOURCE 1
#endif
+#include <linux/openat2.h>
+#include <sys/syscall.h>
+#endif
+#endif
#include <sys/types.h>
#include <sys/stat.h>
@@ -30,12 +38,6 @@ long max = pathconf("/", _PC_PATH_MAX);
#include <string.h>
#include <unistd.h>
-/* for openat2: */
-#ifdef __linux__
-#include <linux/openat2.h>
-#include <sys/syscall.h>
-#endif
-
#include "../include/common.h"
/* check that a file changed
@@ -108,7 +110,7 @@ fsync_dir(const char *path)
if_err_sys((rval = fsync_on_eintr(dirfd)) == -1))
goto err_fsync_dir;
- close_on_eintr(&dirfd);
+ xclose(&dirfd);
free_and_set_null(&dirbuf);
reset_caller_errno(rval);
@@ -116,12 +118,12 @@ fsync_dir(const char *path)
err_fsync_dir:
free_and_set_null(&dirbuf);
- close_on_eintr(&dirfd);
+ xclose(&dirfd);
return with_fallback_errno(EIO);
}
-/* rw_file_exact() - Read perfectly or die
+/* rw_exact() - Read perfectly or die
*
* Read/write, and absolutely insist on an
* absolute read; e.g. if 100 bytes are
@@ -139,8 +141,8 @@ err_fsync_dir:
*/
ssize_t
-rw_file_exact(int fd, unsigned char *mem, size_t nrw,
- off_t off, int rw_type, size_t max_retries)
+rw_exact(int fd, unsigned char *mem, size_t nrw,
+ off_t off, int rw_type)
{
int saved_errno = errno;
ssize_t rval = 0;
@@ -148,17 +150,17 @@ rw_file_exact(int fd, unsigned char *mem, size_t nrw,
size_t nrw_cur;
off_t off_cur;
void *mem_cur;
- size_t retries_on_zero = 0;
errno = 0;
if (io_args(fd, mem, nrw, off, rw_type) == -1)
- goto err_rw_file_exact;
+ goto err_rw_exact;
while (1) {
/* Prevent theoretical overflow */
- if (if_err(rval >= 0 && (size_t)rval > (nrw - rc), EOVERFLOW))
- goto err_rw_file_exact;
+ if (if_err(rval >= 0 && (size_t)rval > (nrw - (size_t)rc),
+ EOVERFLOW))
+ goto err_rw_exact;
rc += rval;
if ((size_t)rc >= nrw)
@@ -168,42 +170,39 @@ rw_file_exact(int fd, unsigned char *mem, size_t nrw,
nrw_cur = (size_t)(nrw - (size_t)rc);
if (if_err(off < 0, EOVERFLOW))
- goto err_rw_file_exact;
+ goto err_rw_exact;
off_cur = off + (off_t)rc;
- if ((rval = rw(fd, mem_cur, nrw_cur, off_cur, rw_type)) < 0)
- goto err_rw_file_exact;
-
- if (rval == 0) {
- if (retries_on_zero++ < max_retries)
- continue;
-
- goto err_rw_file_exact;
- }
-
- retries_on_zero = 0;
+ if ((rval = rw(fd, mem_cur, nrw_cur, off_cur, rw_type)) <= 0)
+ goto err_rw_exact;
}
if (if_err((size_t)rc != nrw, EIO) ||
(rval = rw_over_nrw(rc, nrw)) < 0)
- goto err_rw_file_exact;
+ goto err_rw_exact;
reset_caller_errno(rval);
return rval;
-err_rw_file_exact:
+err_rw_exact:
return with_fallback_errno(EIO);
}
-/* rw() - read-write but with more
+/**
+ * rw() - read-write but with more
* safety checks than barebones libc
*
* A fallback is provided for regular read/write.
* rw_type can be IO_READ (read), IO_WRITE (write),
* IO_PREAD (pread) or IO_PWRITE
+ *
+ * WARNING: this function allows zero-byte returns.
+ * this is intentional, to mimic libc behaviour.
+ * use rw_exact if you need to avoid this.
+ * (ditto partial writes/reads)
+ *
*/
-
ssize_t
rw(int fd, void *mem, size_t nrw,
off_t off, int rw_type)
@@ -213,27 +212,34 @@ rw(int fd, void *mem, size_t nrw,
int saved_errno = errno;
errno = 0;
- if (io_args(fd, mem, nrw, off, rw_type) == -1)
- return with_fallback_errno(EINVAL);
-
- switch (rw_type) {
- case IO_WRITE:
- r = write_on_eintr(fd, mem, nrw);
- break;
- case IO_READ:
- r = read_on_eintr(fd, mem, nrw);
- break;
- case IO_PWRITE:
- r = pwrite_on_eintr(fd, mem, nrw, off);
- break;
- case IO_PREAD:
- r = pread_on_eintr(fd, mem, nrw, off);
- break;
- default:
- errno = EINVAL;
- break;
- }
+ if (io_args(fd, mem, nrw, off, rw_type) == -1 ||
+ if_err(mem == NULL, EFAULT) ||
+ if_err(fd < 0, EBADF) ||
+ if_err(off < 0, EFAULT) ||
+ if_err(nrw == 0, EINVAL))
+ return with_fallback_errno(EIO);
+
+ do {
+ switch (rw_type) {
+ case IO_READ:
+ r = read(fd, mem, nrw);
+ break;
+ case IO_WRITE:
+ r = write(fd, mem, nrw);
+ break;
+ case IO_PREAD:
+ r = pread(fd, mem, nrw, off);
+ break;
+ case IO_PWRITE:
+ r = pwrite(fd, mem, nrw, off);
+ break;
+ default:
+ errno = EINVAL;
+ break;
+ }
+ } while (rw_retry(saved_errno, r));
+
if ((rval = rw_over_nrw(r, nrw)) < 0)
return with_fallback_errno(EIO);
@@ -413,7 +419,7 @@ fs_resolve_at(int dirfd, const char *path, int flags)
/* close previous fd if not the original input */
if (curfd != dirfd)
- close_on_eintr(&curfd);
+ xclose(&curfd);
curfd = nextfd;
nextfd = -1;
@@ -426,11 +432,11 @@ err:
saved_errno = errno;
if (nextfd >= 0)
- close_on_eintr(&nextfd);
+ xclose(&nextfd);
/* close curfd only if it's not the original */
if (curfd != dirfd && curfd >= 0)
- close_on_eintr(&curfd);
+ xclose(&curfd);
errno = saved_errno;
return with_fallback_errno(EIO);
@@ -609,13 +615,14 @@ open_file_on_eintr(const char *path,
}
-#ifdef __linux__ /* we use openat2 on linux */
+#if defined(__linux__) && \
+ ((USE_OPENAT) < 1) /* we use openat2 on linux */
int
openat_on_eintr(int dirfd, const char *path,
int flags, mode_t mode)
{
struct open_how how = {
- .flags = flags,
+ .flags = (unsigned long long)flags,
.mode = mode,
.resolve =
RESOLVE_BENEATH |
@@ -696,90 +703,6 @@ mkdirat_on_eintr(int dirfd,
return rval;
}
-ssize_t
-read_on_eintr(int fd,
- void *buf, size_t count)
-{
- int saved_errno = errno;
- ssize_t rval = 0;
- errno = 0;
-
- if (if_err(buf == NULL, EFAULT) ||
- if_err(fd < 0, EBADF) ||
- if_err(count == 0, EINVAL))
- return with_fallback_errno(EIO);
-
- while (rw_retry(saved_errno,
- rval = read(fd, buf, count)));
-
- reset_caller_errno(rval);
- return rval;
-}
-
-ssize_t
-pread_on_eintr(int fd,
- void *buf, size_t count,
- off_t off)
-{
- int saved_errno = errno;
- ssize_t rval = 0;
- errno = 0;
-
- if (if_err(buf == NULL, EFAULT) ||
- if_err(fd < 0, EBADF) ||
- if_err(off < 0, EFAULT) ||
- if_err(count == 0, EINVAL))
- return with_fallback_errno(EIO);
-
- while (rw_retry(saved_errno,
- rval = pread(fd, buf, count, off)));
-
- reset_caller_errno(rval);
- return rval;
-}
-
-ssize_t
-write_on_eintr(int fd,
- void *buf, size_t count)
-{
- int saved_errno = errno;
- ssize_t rval = 0;
- errno = 0;
-
- if (if_err(buf == NULL, EFAULT) ||
- if_err(fd < 0, EBADF) ||
- if_err(count == 0, EINVAL))
- return with_fallback_errno(EIO);
-
- while (rw_retry(saved_errno,
- rval = write(fd, buf, count)));
-
- reset_caller_errno(rval);
- return rval;
-}
-
-ssize_t
-pwrite_on_eintr(int fd,
- void *buf, size_t count,
- off_t off)
-{
- int saved_errno = errno;
- ssize_t rval = 0;
- errno = 0;
-
- if (if_err(buf == NULL, EFAULT) ||
- if_err(fd < 0, EBADF) ||
- if_err(off < 0, EFAULT) ||
- if_err(count == 0, EINVAL))
- return with_fallback_errno(EIO);
-
- while (rw_retry(saved_errno,
- rval = pwrite(fd, buf, count, off)));
-
- reset_caller_errno(rval);
- return rval;
-}
-
int
fsync_on_eintr(int fd)
{
@@ -798,22 +721,19 @@ fsync_on_eintr(int fd)
}
void
-close_on_eintr(int *fd)
+xclose(int *fd)
{
int saved_errno = errno;
int rval = 0;
if (fd == NULL)
- exitf("close_on_eintr: null pointer");
+ exitf("xclose: null pointer");
if (*fd < 0)
return;
errno = 0;
- while (fs_retry(saved_errno,
- rval = close(*fd)));
-
- if (rval < 0)
- exitf("close_on_eintr: could not close");
+ if ((rval = close(*fd)) < 0)
+ exitf("xclose: could not close");
*fd = -1;
diff --git a/util/libreboot-utils/lib/io.c b/util/libreboot-utils/lib/io.c
index f8e67977..5a1b121d 100644
--- a/util/libreboot-utils/lib/io.c
+++ b/util/libreboot-utils/lib/io.c
@@ -108,16 +108,16 @@ read_file(void)
/* read main file
*/
- _r = rw_file_exact(f->gbe_fd, f->buf, f->gbe_file_size,
- 0, IO_PREAD, MAX_ZERO_RW_RETRY);
+ _r = rw_exact(f->gbe_fd, f->buf, f->gbe_file_size,
+ 0, IO_PREAD);
if (_r < 0)
exitf("%s: read failed", f->fname);
/* copy to tmpfile
*/
- _r = rw_file_exact(f->tmp_fd, f->buf, f->gbe_file_size,
- 0, IO_PWRITE, MAX_ZERO_RW_RETRY);
+ _r = rw_exact(f->tmp_fd, f->buf, f->gbe_file_size,
+ 0, IO_PWRITE);
if (_r < 0)
exitf("%s: %s: copy failed",
@@ -139,8 +139,8 @@ read_file(void)
if (fsync_on_eintr(f->tmp_fd) == -1)
exitf("%s: fsync (tmpfile copy)", f->tname);
- _r = rw_file_exact(f->tmp_fd, f->bufcmp, f->gbe_file_size,
- 0, IO_PREAD, MAX_ZERO_RW_RETRY);
+ _r = rw_exact(f->tmp_fd, f->bufcmp, f->gbe_file_size,
+ 0, IO_PREAD);
if (_r < 0)
exitf("%s: read failed (cmp)", f->tname);
@@ -251,8 +251,8 @@ write_to_gbe_bin(void)
saved_errno = errno;
- close_on_eintr(&f->tmp_fd);
- close_on_eintr(&f->gbe_fd);
+ xclose(&f->tmp_fd);
+ xclose(&f->gbe_fd);
errno = saved_errno;
@@ -437,7 +437,7 @@ gbe_mv(void)
tmp_gbe_bin_exists = 0;
if (f->gbe_fd > -1) {
- close_on_eintr(&f->gbe_fd);
+ xclose(&f->gbe_fd);
if (fsync_dir(f->fname) < 0) {
f->io_err_gbe_bin = 1;
@@ -445,7 +445,7 @@ gbe_mv(void)
}
}
- close_on_eintr(&f->tmp_fd);
+ xclose(&f->tmp_fd);
/* before this function is called,
* tmp_fd may have been moved
@@ -556,8 +556,7 @@ rw_gbe_file_exact(int fd, unsigned char *mem, size_t nrw,
if (nrw > (size_t)GBE_PART_SIZE)
goto err_rw_gbe_file_exact;
- r = rw_file_exact(fd, mem, nrw, off, rw_type,
- MAX_ZERO_RW_RETRY);
+ r = rw_exact(fd, mem, nrw, off, rw_type);
return rw_over_nrw(r, nrw);
diff --git a/util/libreboot-utils/lib/mkhtemp.c b/util/libreboot-utils/lib/mkhtemp.c
index 4d7ad0bd..8591e817 100644
--- a/util/libreboot-utils/lib/mkhtemp.c
+++ b/util/libreboot-utils/lib/mkhtemp.c
@@ -4,10 +4,23 @@
* Hardened mktemp (be nice to the demon).
*/
-#if defined(__linux__) && !defined(_GNU_SOURCE)
-/* for openat2 syscall on linux */
+/* for openat2 / fast path: */
+#ifdef __linux__
+#if !defined(USE_OPENAT) || \
+ ((USE_OPENAT) < 1) /* if 1: use openat, not openat2 */
+#ifndef _GNU_SOURCE
#define _GNU_SOURCE 1
#endif
+#include <sys/syscall.h>
+#include <linux/openat2.h>
+#ifndef O_TMPFILE
+#define O_TMPFILE 020000000
+#endif
+#ifndef AT_EMPTY_PATH
+#define AT_EMPTY_PATH 0x1000
+#endif
+#endif
+#endif
#include <sys/types.h>
#include <sys/stat.h>
@@ -19,18 +32,6 @@
#include <string.h>
#include <unistd.h>
-/* for openat2 / fast path: */
-#ifdef __linux__
-#include <linux/openat2.h>
-#include <sys/syscall.h>
-#ifndef O_TMPFILE
-#define O_TMPFILE 020000000
-#endif
-#ifndef AT_EMPTY_PATH
-#define AT_EMPTY_PATH 0x1000
-#endif
-#endif
-
#include "../include/common.h"
/* note: tmpdir is an override of TMPDIR or /tmp or /var/tmp */
@@ -133,7 +134,7 @@ new_tmp_common(int *fd, char **path, int type,
if (*fd < 0)
goto err;
- close_on_eintr(&dirfd);
+ xclose(&dirfd);
errno = saved_errno;
*path = dest;
@@ -144,8 +145,8 @@ new_tmp_common(int *fd, char **path, int type,
err:
free_and_set_null(&dest);
- close_on_eintr(&dirfd);
- close_on_eintr(fd);
+ xclose(&dirfd);
+ xclose(fd);
/* where a TMPDIR isn't found, and we err,
* we pass this back through for the
@@ -289,8 +290,8 @@ success_same_dir:
rval = 1; /* SUCCESS */
}
- close_on_eintr(&fd_a);
- close_on_eintr(&fd_b);
+ xclose(&fd_a);
+ xclose(&fd_b);
/* we reset caller errno regardless
* of success, so long as it's not
@@ -302,8 +303,8 @@ success_same_dir:
err_same_dir:
/* FAILURE (probably syscall) - returns -1
*/
- close_on_eintr(&fd_a);
- close_on_eintr(&fd_b);
+ xclose(&fd_a);
+ xclose(&fd_b);
return with_fallback_errno(EIO); /* -1 */
}
@@ -358,12 +359,12 @@ sticky_heaven:
if (faccessat(dirfd, ".", X_OK, AT_EACCESS) < 0)
goto sticky_hell; /* down you go! */
- close_on_eintr(&dirfd);
+ xclose(&dirfd);
reset_caller_errno(0);
return 1;
sticky_hell:
- close_on_eintr(&dirfd);
+ xclose(&dirfd);
(void) with_fallback_errno(EPERM);
return 0;
}
@@ -494,7 +495,7 @@ mkhtemp(int *fd,
errno = EEXIST;
err:
- close_on_eintr(fd);
+ xclose(fd);
free_and_set_null(&fname_copy);
return with_fallback_errno(EIO);
@@ -541,7 +542,8 @@ mkhtemp_try_create(int dirfd,
goto err;
if (type == MKHTEMP_FILE) {
-#ifdef __linux__
+#if defined(__linux__) && \
+ (!defined(USE_OPENAT) || ((USE_OPENAT) < 1))
/* try O_TMPFILE fast path */
if (mkhtemp_tmpfile_linux(dirfd,
st_dir_first, fname_copy,
@@ -633,7 +635,7 @@ out:
reset_caller_errno(0);
return rval;
err:
- close_on_eintr(fd);
+ xclose(fd);
if (file_created)
(void) unlinkat(dirfd, fname_copy, 0);
@@ -650,7 +652,8 @@ err:
we still use openat() on bsd, which is
still ok with our other mitigations
*/
-#ifdef __linux__
+#if defined(__linux__) && \
+ (!defined(USE_OPENAT) || ((USE_OPENAT) < 1))
int
mkhtemp_tmpfile_linux(int dirfd,
struct stat *st_dir_first,
@@ -718,7 +721,7 @@ err:
if (linked)
(void) unlinkat(dirfd, fname_copy, 0);
- close_on_eintr(&tmpfd);
+ xclose(&tmpfd);
return with_fallback_errno(EIO);
out:
reset_caller_errno(0);
diff --git a/util/libreboot-utils/lib/rand.c b/util/libreboot-utils/lib/rand.c
index 082612d6..153798f6 100644
--- a/util/libreboot-utils/lib/rand.c
+++ b/util/libreboot-utils/lib/rand.c
@@ -4,31 +4,30 @@
* Random number generation
*/
-#ifndef RAND_H
-#define RAND_H
-
+#if defined(USE_ARC4) && \
+ ((USE_ARC4) > 0)
+#define _DEFAULT_SOURCE 1 /* for arc4random on *linux* */
+ /* (not needed on bsd - on bsd,
+ it is used automatically unless
+ overridden with USE_URANDOM */
+#elif defined(USE_URANDOM) && \
+ ((USE_URANDOM) > 0)
+#include <fcntl.h> /* if not arc4random: /dev/urandom */
+#elif defined(__linux__) && \
+ !(defined(USE_ARC4) && ((USE_ARC4) > 0))
#ifndef _GNU_SOURCE
#define _GNU_SOURCE 1
#endif
+#include <sys/syscall.h>
+#include <sys/random.h>
+#endif
#ifdef __OpenBSD__
#include <sys/param.h>
#endif
#include <sys/types.h>
-#ifndef USE_URANDOM
-#define USE_URANDOM 0
-#endif
-
#include <errno.h>
-#if defined(USE_URANDOM) && \
- ((USE_URANDOM) > 0)
-#include <fcntl.h> /* if not arc4random: /dev/urandom */
-#elif defined(__linux__)
-#include <sys/random.h>
-#include <sys/syscall.h>
-#endif
-
#include <fcntl.h>
#include <limits.h>
#include <stddef.h>
@@ -139,10 +138,15 @@ rset(void *buf, size_t n)
if (n == 0)
exitf("rset: zero-byte request");
-#if (defined(__OpenBSD__) || defined(__FreeBSD__) || \
+/* on linux, getrandom is recommended,
+ but you can pass -DUSE_ARC4=1 to use arc4random.
+ useful for portability testing from linux.
+ */
+#if (defined(USE_ARC4) && ((USE_ARC4) > 0)) || \
+ ((defined(__OpenBSD__) || defined(__FreeBSD__) || \
defined(__NetBSD__) || defined(__APPLE__) || \
defined(__DragonFly__)) && !(defined(USE_URANDOM) && \
- ((USE_URANDOM) > 0))
+ ((USE_URANDOM) > 0)))
arc4random_buf(buf, n);
#else
@@ -158,8 +162,7 @@ retry_rand: {
open_file_on_eintr("/dev/urandom", &fd, O_RDONLY, 0400, NULL);
while (rw_retry(saved_errno,
- rc = read_on_eintr(fd,
- (unsigned char *)buf + off, n - off, 0)));
+ rc = rw(fd, (unsigned char *)buf + off, n - off, 0, IO_READ)));
#elif defined(__linux__)
long rc;
while (sys_retry(saved_errno,
@@ -169,18 +172,21 @@ retry_rand: {
#error Unsupported operating system (possibly unsecure randomisation)
#endif
- if (rc < 0)
- goto err; /* syscall fehler */
-
- if (rc == 0)
- goto err; /* prevent infinite loop on fatal err */
+ if (rc < 0 || /* syscall fehler */
+ rc == 0) { /* prevent infinite loop on fatal err */
+#if defined(USE_URANDOM) && \
+ ((USE_URANDOM) > 0)
+ xclose(&fd);
+#endif
+ goto err;
+ }
if ((off += (size_t)rc) < n)
goto retry_rand;
#if defined(USE_URANDOM) && \
((USE_URANDOM) > 0)
- close_on_eintr(&fd);
+ xclose(&fd);
#endif
}
@@ -188,12 +194,7 @@ retry_rand: {
reset_caller_errno(0);
return;
err:
-#if defined(USE_URANDOM) && \
- ((USE_URANDOM) > 0)
- close_on_eintr(&fd);
-#endif
(void) with_fallback_errno(ECANCELED);
exitf("Randomisierungsfehler");
exit(EXIT_FAILURE);
}
-#endif
diff --git a/util/libreboot-utils/lib/state.c b/util/libreboot-utils/lib/state.c
index b956a483..78e15134 100644
--- a/util/libreboot-utils/lib/state.c
+++ b/util/libreboot-utils/lib/state.c
@@ -4,8 +4,8 @@
* State machine (singleton) for nvmutil data.
*/
-#ifndef _GNU_SOURCE
-#define _GNU_SOURCE 1
+#ifndef _XOPEN_SOURCE
+#define _XOPEN_SOURCE 700
#endif
#include <sys/types.h>
diff --git a/util/libreboot-utils/mkhtemp.c b/util/libreboot-utils/mkhtemp.c
index ced8aa96..86aab536 100644
--- a/util/libreboot-utils/mkhtemp.c
+++ b/util/libreboot-utils/mkhtemp.c
@@ -16,9 +16,8 @@
* while the specification that it implements evolves.
*/
-#if defined(__linux__) && !defined(_GNU_SOURCE)
-/* for openat2 on linux */
-#define _GNU_SOURCE 1
+#ifndef _XOPEN_SOURCE
+#define _XOPEN_SOURCE 700
#endif
#include <sys/types.h>
diff --git a/util/libreboot-utils/nvmutil.c b/util/libreboot-utils/nvmutil.c
index 46e4a15c..66e47ec8 100644
--- a/util/libreboot-utils/nvmutil.c
+++ b/util/libreboot-utils/nvmutil.c
@@ -6,10 +6,6 @@
* These images configure your Intel Gigabit Ethernet adapter.
*/
-#ifndef _GNU_SOURCE
-#define _GNU_SOURCE 1
-#endif
-
#include <sys/types.h>
#include <sys/stat.h>
@@ -112,8 +108,8 @@ exit_cleanup(void)
f = &x->f;
/* close fds if still open */
- close_on_eintr(&f->tmp_fd);
- close_on_eintr(&f->gbe_fd);
+ xclose(&f->tmp_fd);
+ xclose(&f->gbe_fd);
/* unlink tmpfile if it exists */
if (f->tname != NULL) {