diff options
Diffstat (limited to 'devel/efivar/files/patch-src_efivarfs.c')
-rw-r--r-- | devel/efivar/files/patch-src_efivarfs.c | 162 |
1 files changed, 162 insertions, 0 deletions
diff --git a/devel/efivar/files/patch-src_efivarfs.c b/devel/efivar/files/patch-src_efivarfs.c new file mode 100644 index 000000000000..1ca8a549aba8 --- /dev/null +++ b/devel/efivar/files/patch-src_efivarfs.c @@ -0,0 +1,162 @@ +--- src/efivarfs.c.orig 2024-01-31 20:08:46 UTC ++++ src/efivarfs.c +@@ -9,20 +9,32 @@ + #include <err.h> + #include <errno.h> + #include <fcntl.h> +-#include <linux/magic.h> ++#if defined(__linux__) ++# include <linux/magic.h> ++#endif + #include <stdio.h> + #include <stdlib.h> + #include <string.h> + #include <sys/mman.h> + #include <sys/types.h> ++#include <sys/param.h> ++#include <sys/mount.h> + #include <sys/stat.h> + #include <sys/uio.h> +-#include <sys/vfs.h> ++#if defined(__linux__) ++# include <sys/vfs.h> ++#endif + #include <unistd.h> + ++#if defined(__FreeBSD__) ++# undef LIST_HEAD ++#endif ++ + #include "efivar.h" + +-#include <linux/fs.h> ++#if defined(__linux__) ++# include <linux/fs.h> ++#endif + + #ifndef EFIVARFS_MAGIC + # define EFIVARFS_MAGIC 0xde5e81e4 +@@ -102,6 +114,7 @@ efivarfs_set_fd_immutable(int fd, int immutable) + static int + efivarfs_set_fd_immutable(int fd, int immutable) + { ++#if defined(__linux__) + unsigned int flags; + int rc = 0; + +@@ -124,11 +137,42 @@ efivarfs_set_fd_immutable(int fd, int immutable) + } + + return rc; ++#elif defined(__FreeBSD__) ++ struct stat sb; ++ int rc = 0; ++ unsigned long flags; ++ ++ if (fstat(fd, &sb) == -1) { ++ if (errno == EBADF) ++ rc = 0; ++ else ++ efi_error("fstat(%d) failed", fd); ++ return rc; ++ } ++ ++ flags = sb.st_flags; ++ ++ if ((immutable && !(flags & UF_IMMUTABLE)) || ++ (!immutable && (flags & UF_IMMUTABLE))) { ++ if (immutable) ++ flags |= UF_IMMUTABLE; ++ else ++ flags &= ~UF_IMMUTABLE; ++ ++ if (chflagsat(fd, "", flags, AT_EMPTY_PATH) == -1) { ++ efi_error("chflagsat(%d) failed\n", fd); ++ rc = -1; ++ } ++ } ++ ++ return rc; ++#endif + } + + static int + efivarfs_make_fd_mutable(int fd, unsigned long *orig_attrs) + { ++#if defined(__linux__) + unsigned long mutable_attrs = 0; + + *orig_attrs = 0; +@@ -145,6 +189,26 @@ efivarfs_make_fd_mutable(int fd, unsigned long *orig_a + return -1; + + return 0; ++#elif defined(__FreeBSD__) ++ struct stat sb; ++ ++ *orig_attrs = 0; ++ ++ if (fstat(fd, &sb) == -1) ++ return -1; ++ ++ *orig_attrs = sb.st_flags; ++ ++ // if the file is not immutable, nothing to do ++ if ((sb.st_flags & UF_IMMUTABLE) == 0) ++ return 0; ++ ++ // remove user immutable flag ++ if (chflagsat(fd, "", sb.st_flags & ~UF_IMMUTABLE, AT_EMPTY_PATH) == -1) ++ return -1; ++ ++ return 0; ++#endif + } + + static int +@@ -375,10 +439,17 @@ efivarfs_set_variable(efi_guid_t guid, const char *nam + goto err; + } + ++#if defined(__linux__) + /* if the file is indeed immutable, clear and remember it */ + if (efivarfs_make_fd_mutable(rfd, &orig_attrs) == 0 && + (orig_attrs & FS_IMMUTABLE_FL)) + restore_immutable_fd = rfd; ++#elif defined(__FreeBSD__) ++ /* if the file is indeed immutable, clear and remember it */ ++ if (efivarfs_make_fd_mutable(rfd, &orig_attrs) == 0 && ++ (orig_attrs & UF_IMMUTABLE)) ++ restore_immutable_fd = rfd; ++#endif + } + + /* +@@ -414,9 +485,15 @@ efivarfs_set_variable(efi_guid_t guid, const char *nam + * immediately, and the write() below would fail otherwise. + */ + if (rfd == -1) { ++#if defined(__linux__) + if (efivarfs_make_fd_mutable(wfd, &orig_attrs) == 0 && + (orig_attrs & FS_IMMUTABLE_FL)) + restore_immutable_fd = wfd; ++#elif defined(__FreeBSD__) ++ if (efivarfs_make_fd_mutable(wfd, &orig_attrs) == 0 && ++ (orig_attrs & UF_IMMUTABLE)) ++ restore_immutable_fd = wfd; ++#endif + } else { + /* make sure rfd and wfd refer to the same file */ + struct stat wfd_stat; +@@ -452,7 +529,11 @@ err: + if (ret == -1 && rfd == -1 && wfd != -1 && unlink(path) == -1) + efi_error("failed to unlink %s", path); + ++#if defined(__linux__) + ioctl(restore_immutable_fd, FS_IOC_SETFLAGS, &orig_attrs); ++#elif defined(__FreeBSD__) ++ chflagsat(restore_immutable_fd, "", orig_attrs, AT_EMPTY_PATH); ++#endif + + if (wfd >= 0) + close(wfd); |