summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLeah Rowe <leah@libreboot.org>2026-03-22 23:37:43 +0000
committerLeah Rowe <leah@libreboot.org>2026-03-22 23:43:03 +0000
commit1684f475cda9219db7a593b6fa5345c7185117f3 (patch)
tree2ea2829360ccec0a036ef26f38638bf89d8640ae
parentcf4be895f9e3c40cebc7c85ee049386b927d1ee3 (diff)
WIP identity check unification
Signed-off-by: Leah Rowe <leah@libreboot.org>
-rw-r--r--util/nvmutil/include/common.h2
-rw-r--r--util/nvmutil/lib/file.c52
2 files changed, 36 insertions, 18 deletions
diff --git a/util/nvmutil/include/common.h b/util/nvmutil/include/common.h
index 6ae7af04..0fedeedd 100644
--- a/util/nvmutil/include/common.h
+++ b/util/nvmutil/include/common.h
@@ -330,6 +330,8 @@ int fd_verify_regular(int fd,
int fd_verify_identity(int fd,
const struct stat *expected,
struct stat *out);
+int fd_verify_dir_identity(int fd,
+ const struct stat *expected);
int is_owner(struct stat *st);
int lock_file(int fd, int flags);
int same_file(int fd, struct stat *st_old, int check_size);
diff --git a/util/nvmutil/lib/file.c b/util/nvmutil/lib/file.c
index a4ce7b89..f0cb5ad4 100644
--- a/util/nvmutil/lib/file.c
+++ b/util/nvmutil/lib/file.c
@@ -831,11 +831,8 @@ mkhtemp_try_create(int dirfd,
if (fstat(dirfd, &st_dir_now) < 0)
goto err;
- if (st_dir_now.st_dev != st_dir_initial->st_dev ||
- st_dir_now.st_ino != st_dir_initial->st_ino) {
- errno = ESTALE;
+ if (fd_verify_dir_identity(dirfd, st_dir_initial) < 0)
goto err;
- }
*fd = openat2p(dirfd, fname_copy,
O_RDWR | O_CREAT | O_EXCL |
@@ -860,14 +857,8 @@ mkhtemp_try_create(int dirfd,
if (fstat(*fd, &st_open) < 0)
goto err;
- if (fstat(dirfd, &st_dir_now) < 0)
- goto err;
-
- if (st_dir_now.st_dev != st_dir_initial->st_dev ||
- st_dir_now.st_ino != st_dir_initial->st_ino) {
- errno = ESTALE;
+ if (fd_verify_dir_identity(dirfd, st_dir_initial) < 0)
goto err;
- }
if (secure_file(fd, st, &st_open,
O_APPEND, 1, 1, 0600) < 0)
@@ -1116,6 +1107,36 @@ fd_verify_identity(int fd,
}
int
+fd_verify_dir_identity(int fd,
+ const struct stat *expected)
+{
+ struct stat st_now;
+ int saved_errno = errno;
+
+ if (fd < 0 || expected == NULL) {
+ errno = EFAULT;
+ return -1;
+ }
+
+ if (fstat(fd, &st_now) < 0)
+ return -1;
+
+ if (st_now.st_dev != expected->st_dev ||
+ st_now.st_ino != expected->st_ino) {
+ errno = ESTALE;
+ return -1;
+ }
+
+ if (!S_ISDIR(st_now.st_mode)) {
+ errno = ENOTDIR;
+ return -1;
+ }
+
+ errno = saved_errno;
+ return 0;
+}
+
+int
is_owner(struct stat *st)
{
if (st == NULL) {
@@ -1802,14 +1823,9 @@ fs_mkdir_p_at(int dirfd, const char *path, mode_t mode)
break;
/* check parent integrity */
- if (fstat(dirfd, &st_parent_now) < 0)
- goto err;
-
- if (st_parent_now.st_dev != st_parent_initial.st_dev ||
- st_parent_now.st_ino != st_parent_initial.st_ino) {
- errno = ESTALE;
+ if (fd_verify_identity(dirfd, &st_parent_initial,
+ &st_parent_now) < 0)
goto err;
- }
nextfd = openat2p(dirfd, name,
O_RDONLY | O_DIRECTORY | O_CLOEXEC, 0);