diff options
| author | Leah Rowe <leah@libreboot.org> | 2026-03-22 23:37:43 +0000 |
|---|---|---|
| committer | Leah Rowe <leah@libreboot.org> | 2026-03-22 23:43:03 +0000 |
| commit | 1684f475cda9219db7a593b6fa5345c7185117f3 (patch) | |
| tree | 2ea2829360ccec0a036ef26f38638bf89d8640ae /util | |
| parent | cf4be895f9e3c40cebc7c85ee049386b927d1ee3 (diff) | |
WIP identity check unification
Signed-off-by: Leah Rowe <leah@libreboot.org>
Diffstat (limited to 'util')
| -rw-r--r-- | util/nvmutil/include/common.h | 2 | ||||
| -rw-r--r-- | util/nvmutil/lib/file.c | 52 |
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); |
