diff options
Diffstat (limited to 'util/libreboot-utils/lib/file.c')
| -rw-r--r-- | util/libreboot-utils/lib/file.c | 103 |
1 files changed, 19 insertions, 84 deletions
diff --git a/util/libreboot-utils/lib/file.c b/util/libreboot-utils/lib/file.c index 552618d6..5fdef7b3 100644 --- a/util/libreboot-utils/lib/file.c +++ b/util/libreboot-utils/lib/file.c @@ -69,29 +69,6 @@ err_same_file: return -1; } -/* open() but with abort traps - */ -/* TODO: also support other things here than files. - and then use, throughout the program. - in particular, use of openat might help - (split the path) - (see: link attack mitigations throughout nvmutil) - - make it return, and handle the return value/errno - - (this could return e.g. EINTR) - - TODO: this function is not used by mkhtemp, nor will - it probably be, it's currently used by nvmutil, - for opening intel gbe nvm config files. i can - probably remove it though and unify witth some - of the verification code now used for mkhtemp - -TODO: and don't abort. return -1. and handle in the caller. - -minor obstacle: the mkhtemp code always requires absolute -paths, whereas the gbe editor takes relative paths. - */ void xopen(int *fd_ptr, const char *path, int flags, struct stat *st) { @@ -108,10 +85,6 @@ xopen(int *fd_ptr, const char *path, int flags, struct stat *st) err_no_cleanup(0, errno, "%s: file not seekable", path); } -/* fsync() the directory of a file, - * useful for atomic writes - */ - int fsync_dir(const char *path) { @@ -196,19 +169,6 @@ err_fsync_dir: return -1; } -/* - * Safe I/O functions wrapping around - * read(), write() and providing a portable - * analog of both pread() and pwrite(). - * These functions are designed for maximum - * robustness, checking NULL inputs, overflowed - * outputs, and all kinds of errors that the - * standard libc functions don't. - * - * Looping on EINTR and EAGAIN is supported. - * EINTR/EAGAIN looping is done indefinitely. - */ - /* rw_file_exact() - Read perfectly or die * * Read/write, and absolutely insist on an @@ -243,6 +203,7 @@ rw_file_exact(int fd, unsigned char *mem, size_t nrw, size_t retries_on_zero; int saved_errno = errno; + errno = 0; rval = 0; @@ -317,12 +278,6 @@ err_rw_file_exact: /* prw() - portable read-write with more * safety checks than barebones libc * - * portable pwrite/pread on request, or real - * pwrite/pread libc functions can be used. - * the portable (non-libc) pread/pwrite is not - * thread-safe, because it does not prevent or - * mitigate race conditions on file descriptors - * * If you need real pwrite/pread, just compile * with flag: REAL_POS_IO=1 * @@ -340,6 +295,11 @@ err_rw_file_exact: * a change was detected, assuming * nothing else is touching it now * off_reset 0: never reset if changed + * + * REAL_POS_IO is enabled by default in common.h + * and the fallback version was written for fun. + * You should just use the real one (REAL_POS_IO 1), + * since it is generally more reliable. */ ssize_t @@ -359,6 +319,7 @@ prw(int fd, void *mem, size_t nrw, off_t off_last; #endif int saved_errno = errno; + errno = 0; if (io_args(fd, mem, nrw, off, rw_type) == -1) @@ -568,8 +529,6 @@ err_rw_over_nrw: return -1; } -#if !defined(REAL_POS_IO) || \ - REAL_POS_IO < 1 off_t lseek_on_eintr(int fd, off_t off, int whence, int loop_eagain, int loop_eintr) @@ -588,10 +547,9 @@ lseek_on_eintr(int fd, off_t off, int whence, return old; } -#endif /* two functions that reduce sloccount by - * two hundred lines... no, now three. */ + * two hundred lines */ int if_err(int condition, int errval) { @@ -603,13 +561,6 @@ if_err(int condition, int 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) { @@ -665,10 +616,8 @@ close_warn(int *fd, char *s) return 0; } -/* TODO: remove this. giant liability. - make close calls always err instead, - when they fail. otherwise we hide bugs! - */ +/* TODO: remove this, and just check + * err on every close. */ void close_no_err(int *fd) { @@ -685,7 +634,6 @@ close_no_err(int *fd) /* TODO: make fd a pointer insttead and automatically reset -1 here */ -/* BUT DO NOT reset -1 on error */ int close_on_eintr(int fd) { @@ -732,11 +680,10 @@ fs_rename_at(int olddirfd, const char *old, return renameat(olddirfd, old, newdirfd, new); } -/* secure open, based on - * relative path to root +/* secure open, based on relative path to root * - * always a fixed fd for / - * see: rootfs() + * always a fixed fd for / see: rootfs() + * and fs_resolve_at() */ int fs_open(const char *path, int flags) @@ -751,12 +698,8 @@ fs_open(const char *path, int flags) return fs_resolve_at(fs->rootfd, path + 1, flags); } -/* singleton function - * that returns a fixed - * descriptor of / - * - * used throughout, for - * repeated integrity checks +/* singleton function that returns a fixed descriptor of / + * used throughout, for repeated integrity checks */ struct filesystem * rootfs(void) @@ -778,8 +721,7 @@ rootfs(void) return &global_fs; } -/* filesystem sandboxing. - * (in userspace) +/* filesystem sandboxing in userspace */ int fs_resolve_at(int dirfd, const char *path, int flags) @@ -818,10 +760,9 @@ fs_resolve_at(int dirfd, const char *path, int flags) if (nextfd < 0) goto err; - /* close previous fd IF it is not the original input */ - if (curfd != dirfd) { + /* close previous fd if not the original input */ + if (curfd != dirfd) (void) close_on_eintr(curfd); - } curfd = nextfd; nextfd = -1; @@ -899,8 +840,6 @@ fs_open_component(int dirfd, const char *name, (is_last ? flags : (O_RDONLY | O_DIRECTORY)) | O_NOFOLLOW | O_CLOEXEC, (flags & O_CREAT) ? 0600 : 0); - /* the patient always lies - */ if (!is_last) { if (if_err(fd < 0, EBADF) || @@ -972,9 +911,6 @@ fs_dirname_basename(const char *path, /* portable wrapper for use of openat2 on linux, * with fallback for others e.g. openbsd - * - * BONUS: arg checks - * TODO: consider EINTR/EAGAIN retry loop */ int openat2p(int dirfd, const char *path, @@ -1025,8 +961,7 @@ retry: } int -mkdirat_on_eintr( /* <-- say that 10 times to please the demon */ - int dirfd, +mkdirat_on_eintr(int dirfd, const char *path, mode_t mode) { int saved_errno = errno; |
