mirror of
https://codeberg.org/libreboot/lbmk.git
synced 2026-07-22 14:36:31 +02:00
libreboot-utils: much stricter close() handling
remove close_warn and close_no_err make close_on_eintr a void, and abort on error instead of returning -1. a failed file closure is a world-ending event. burn accordingly. Signed-off-by: Leah Rowe <leah@libreboot.org>
This commit is contained in:
@@ -539,14 +539,12 @@ int secure_file(int *fd,
|
|||||||
int check_seek,
|
int check_seek,
|
||||||
int do_lock,
|
int do_lock,
|
||||||
mode_t mode);
|
mode_t mode);
|
||||||
int close_on_eintr(int fd);
|
void close_on_eintr(int *fd);
|
||||||
int fsync_on_eintr(int fd);
|
int fsync_on_eintr(int fd);
|
||||||
int fs_rename_at(int olddirfd, const char *old,
|
int fs_rename_at(int olddirfd, const char *old,
|
||||||
int newdirfd, const char *new);
|
int newdirfd, const char *new);
|
||||||
int fs_open(const char *path, int flags);
|
int fs_open(const char *path, int flags);
|
||||||
void close_no_err(int *fd);
|
|
||||||
void free_and_set_null(char **buf);
|
void free_and_set_null(char **buf);
|
||||||
int close_warn(int *fd, char *s);
|
|
||||||
struct filesystem *rootfs(void);
|
struct filesystem *rootfs(void);
|
||||||
int fs_resolve_at(int dirfd, const char *path, int flags);
|
int fs_resolve_at(int dirfd, const char *path, int flags);
|
||||||
int fs_next_component(const char **p,
|
int fs_next_component(const char **p,
|
||||||
|
|||||||
@@ -146,11 +146,7 @@ fsync_dir(const char *path)
|
|||||||
if_err_sys(fsync_on_eintr(dirfd) == -1))
|
if_err_sys(fsync_on_eintr(dirfd) == -1))
|
||||||
goto err_fsync_dir;
|
goto err_fsync_dir;
|
||||||
|
|
||||||
if (close_on_eintr(dirfd) == -1) {
|
close_on_eintr(&dirfd);
|
||||||
|
|
||||||
dirfd = -1;
|
|
||||||
goto err_fsync_dir;
|
|
||||||
}
|
|
||||||
|
|
||||||
free_and_set_null(&dirbuf);
|
free_and_set_null(&dirbuf);
|
||||||
|
|
||||||
@@ -163,7 +159,7 @@ err_fsync_dir:
|
|||||||
errno = EIO;
|
errno = EIO;
|
||||||
|
|
||||||
free_and_set_null(&dirbuf);
|
free_and_set_null(&dirbuf);
|
||||||
close_no_err(&dirfd);
|
close_on_eintr(&dirfd);
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -589,66 +585,30 @@ free_and_set_null(char **buf)
|
|||||||
*buf = NULL;
|
*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, and just check
|
|
||||||
* err on every close. */
|
|
||||||
void
|
void
|
||||||
close_no_err(int *fd)
|
close_on_eintr(int *fd)
|
||||||
{
|
|
||||||
int saved_errno = errno;
|
|
||||||
|
|
||||||
if (fd == NULL || *fd < 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
(void) close_on_eintr(*fd);
|
|
||||||
*fd = -1;
|
|
||||||
|
|
||||||
errno = saved_errno;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* TODO: make fd a pointer insttead
|
|
||||||
and automatically reset -1 here */
|
|
||||||
int
|
|
||||||
close_on_eintr(int fd)
|
|
||||||
{
|
{
|
||||||
int r;
|
int r;
|
||||||
int saved_errno = errno;
|
int saved_errno = errno;
|
||||||
|
|
||||||
|
if (fd == NULL)
|
||||||
|
err_exit(EINVAL, "close_on_eintr: null pointer");
|
||||||
|
|
||||||
|
if (*fd < 0)
|
||||||
|
return;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
r = close(fd);
|
r = close(*fd);
|
||||||
} while (r == -1 && (
|
} while (r == -1 && (
|
||||||
errno == EINTR || errno == EAGAIN ||
|
errno == EINTR || errno == EAGAIN ||
|
||||||
errno == EWOULDBLOCK || errno == ETXTBSY));
|
errno == EWOULDBLOCK || errno == ETXTBSY));
|
||||||
|
|
||||||
if (r >= 0)
|
if (r < 0)
|
||||||
errno = saved_errno;
|
err_exit(errno, "close_on_eintr: could not close");
|
||||||
|
|
||||||
return r;
|
*fd = -1;
|
||||||
|
|
||||||
|
errno = saved_errno;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
@@ -761,7 +721,7 @@ fs_resolve_at(int dirfd, const char *path, int flags)
|
|||||||
|
|
||||||
/* close previous fd if not the original input */
|
/* close previous fd if not the original input */
|
||||||
if (curfd != dirfd)
|
if (curfd != dirfd)
|
||||||
(void) close_on_eintr(curfd);
|
close_on_eintr(&curfd);
|
||||||
|
|
||||||
curfd = nextfd;
|
curfd = nextfd;
|
||||||
nextfd = -1;
|
nextfd = -1;
|
||||||
@@ -774,11 +734,11 @@ err:
|
|||||||
saved_errno = errno;
|
saved_errno = errno;
|
||||||
|
|
||||||
if (nextfd >= 0)
|
if (nextfd >= 0)
|
||||||
(void) close_on_eintr(nextfd);
|
close_on_eintr(&nextfd);
|
||||||
|
|
||||||
/* close curfd only if it's not the original */
|
/* close curfd only if it's not the original */
|
||||||
if (curfd != dirfd && curfd >= 0)
|
if (curfd != dirfd && curfd >= 0)
|
||||||
(void) close_on_eintr(curfd);
|
close_on_eintr(&curfd);
|
||||||
|
|
||||||
errno = saved_errno;
|
errno = saved_errno;
|
||||||
return -1;
|
return -1;
|
||||||
@@ -847,7 +807,7 @@ fs_open_component(int dirfd, const char *name,
|
|||||||
|
|
||||||
if (!S_ISDIR(st.st_mode)) {
|
if (!S_ISDIR(st.st_mode)) {
|
||||||
|
|
||||||
(void) close_on_eintr(fd);
|
close_on_eintr(&fd);
|
||||||
errno = ENOTDIR;
|
errno = ENOTDIR;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -239,8 +239,8 @@ write_to_gbe_bin(void)
|
|||||||
|
|
||||||
saved_errno = errno;
|
saved_errno = errno;
|
||||||
|
|
||||||
f->io_err_gbe_bin |= -close_warn(&f->tmp_fd, f->tname);
|
close_on_eintr(&f->tmp_fd);
|
||||||
f->io_err_gbe_bin |= -close_warn(&f->gbe_fd, f->fname);
|
close_on_eintr(&f->gbe_fd);
|
||||||
|
|
||||||
errno = saved_errno;
|
errno = saved_errno;
|
||||||
|
|
||||||
@@ -440,15 +440,8 @@ gbe_mv(void)
|
|||||||
|
|
||||||
ret_gbe_mv:
|
ret_gbe_mv:
|
||||||
|
|
||||||
/* TODO: this whole section is bloat.
|
|
||||||
it can be generalised
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (f->gbe_fd > -1) {
|
if (f->gbe_fd > -1) {
|
||||||
if (close_on_eintr(f->gbe_fd) < 0) {
|
close_on_eintr(&f->gbe_fd);
|
||||||
f->gbe_fd = -1;
|
|
||||||
rval = -1;
|
|
||||||
}
|
|
||||||
f->gbe_fd = -1;
|
f->gbe_fd = -1;
|
||||||
|
|
||||||
if (fsync_dir(f->fname) < 0) {
|
if (fsync_dir(f->fname) < 0) {
|
||||||
@@ -457,13 +450,7 @@ ret_gbe_mv:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (f->tmp_fd > -1) {
|
close_on_eintr(&f->tmp_fd);
|
||||||
if (close_on_eintr(f->tmp_fd) < 0) {
|
|
||||||
f->tmp_fd = -1;
|
|
||||||
rval = -1;
|
|
||||||
}
|
|
||||||
f->tmp_fd = -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* before this function is called,
|
/* before this function is called,
|
||||||
* tmp_fd may have been moved
|
* tmp_fd may have been moved
|
||||||
|
|||||||
@@ -164,7 +164,7 @@ new_tmp_common(int *fd, char **path, int type,
|
|||||||
if (*fd < 0)
|
if (*fd < 0)
|
||||||
goto err;
|
goto err;
|
||||||
|
|
||||||
close_no_err(&dirfd);
|
close_on_eintr(&dirfd);
|
||||||
|
|
||||||
errno = saved_errno;
|
errno = saved_errno;
|
||||||
*path = dest;
|
*path = dest;
|
||||||
@@ -180,8 +180,8 @@ err:
|
|||||||
|
|
||||||
free_and_set_null(&dest);
|
free_and_set_null(&dest);
|
||||||
|
|
||||||
close_no_err(&dirfd);
|
close_on_eintr(&dirfd);
|
||||||
close_no_err(fd);
|
close_on_eintr(fd);
|
||||||
|
|
||||||
/* where a TMPDIR isn't found, and we err,
|
/* where a TMPDIR isn't found, and we err,
|
||||||
* we pass this back through for the
|
* we pass this back through for the
|
||||||
@@ -348,8 +348,8 @@ same_dir(const char *a, const char *b)
|
|||||||
if (st_a.st_dev == st_b.st_dev &&
|
if (st_a.st_dev == st_b.st_dev &&
|
||||||
st_a.st_ino == st_b.st_ino) {
|
st_a.st_ino == st_b.st_ino) {
|
||||||
|
|
||||||
close_no_err(&fd_a);
|
close_on_eintr(&fd_a);
|
||||||
close_no_err(&fd_b);
|
close_on_eintr(&fd_b);
|
||||||
|
|
||||||
success_same_dir:
|
success_same_dir:
|
||||||
|
|
||||||
@@ -360,8 +360,8 @@ success_same_dir:
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
close_no_err(&fd_a);
|
close_on_eintr(&fd_a);
|
||||||
close_no_err(&fd_b);
|
close_on_eintr(&fd_b);
|
||||||
|
|
||||||
/* FAILURE (logical)
|
/* FAILURE (logical)
|
||||||
*/
|
*/
|
||||||
@@ -374,8 +374,8 @@ err_same_dir:
|
|||||||
/* FAILURE (probably syscall)
|
/* FAILURE (probably syscall)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
close_no_err(&fd_a);
|
close_on_eintr(&fd_a);
|
||||||
close_no_err(&fd_b);
|
close_on_eintr(&fd_b);
|
||||||
|
|
||||||
if (errno == saved_errno)
|
if (errno == saved_errno)
|
||||||
errno = EIO;
|
errno = EIO;
|
||||||
@@ -468,7 +468,7 @@ world_writeable_and_sticky(
|
|||||||
|
|
||||||
sticky_heaven:
|
sticky_heaven:
|
||||||
|
|
||||||
close_no_err(&dirfd);
|
close_on_eintr(&dirfd);
|
||||||
errno = saved_errno;
|
errno = saved_errno;
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
@@ -478,7 +478,7 @@ sticky_hell:
|
|||||||
if (errno == saved_errno)
|
if (errno == saved_errno)
|
||||||
errno = EPERM;
|
errno = EPERM;
|
||||||
|
|
||||||
close_no_err(&dirfd);
|
close_on_eintr(&dirfd);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -606,7 +606,7 @@ mkhtemp(int *fd,
|
|||||||
errno = EEXIST;
|
errno = EEXIST;
|
||||||
|
|
||||||
err:
|
err:
|
||||||
close_no_err(fd);
|
close_on_eintr(fd);
|
||||||
|
|
||||||
success:
|
success:
|
||||||
free_and_set_null(&fname_copy);
|
free_and_set_null(&fname_copy);
|
||||||
@@ -732,7 +732,7 @@ mkhtemp_try_create(int dirfd,
|
|||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
err:
|
err:
|
||||||
close_no_err(fd);
|
close_on_eintr(fd);
|
||||||
|
|
||||||
if (file_created)
|
if (file_created)
|
||||||
(void) unlinkat(dirfd, fname_copy, 0);
|
(void) unlinkat(dirfd, fname_copy, 0);
|
||||||
@@ -827,7 +827,7 @@ err:
|
|||||||
if (linked)
|
if (linked)
|
||||||
(void) unlinkat(dirfd, fname_copy, 0);
|
(void) unlinkat(dirfd, fname_copy, 0);
|
||||||
|
|
||||||
close_no_err(&tmpfd);
|
close_on_eintr(&tmpfd);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -169,7 +169,7 @@ retry_rand:
|
|||||||
|
|
||||||
#if defined(USE_URANDOM) && \
|
#if defined(USE_URANDOM) && \
|
||||||
((USE_URANDOM) > 0)
|
((USE_URANDOM) > 0)
|
||||||
close_no_err(&fd);
|
close_on_eintr(&fd);
|
||||||
#endif
|
#endif
|
||||||
goto out;
|
goto out;
|
||||||
#endif
|
#endif
|
||||||
@@ -179,7 +179,7 @@ out:
|
|||||||
err:
|
err:
|
||||||
#if defined(USE_URANDOM) && \
|
#if defined(USE_URANDOM) && \
|
||||||
((USE_URANDOM) > 0)
|
((USE_URANDOM) > 0)
|
||||||
close_no_err(&fd);
|
close_on_eintr(&fd);
|
||||||
#endif
|
#endif
|
||||||
err_exit(ECANCELED,
|
err_exit(ECANCELED,
|
||||||
"Randomisation failure, possibly unsupported in your kernel");
|
"Randomisation failure, possibly unsupported in your kernel");
|
||||||
|
|||||||
Reference in New Issue
Block a user