File mokutil-bsc964726-fix-immutable.patch of Package mokutil.24584
From 0eb97e1b1cf9352969117bf7c9368f8ccf77575e Mon Sep 17 00:00:00 2001
From: Gary Lin <glin@suse.com>
Date: Thu, 16 Jun 2016 14:17:19 +0800
Subject: [PATCH] Change the immutable flag
The upstream patches introduced by bsc#964726 make files in efivarfs
immutable. This patch changes the immutable flag before writing the
variables so that mokutil can change the content of the variable
properly.
Signed-off-by: Gary Lin <glin@suse.com>
---
src/efilib.c | 59 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 58 insertions(+), 1 deletion(-)
diff --git a/src/efilib.c b/src/efilib.c
index 6db914f..1d76893 100644
--- a/src/efilib.c
+++ b/src/efilib.c
@@ -35,6 +35,8 @@
*/
#include <sys/types.h>
#include <sys/stat.h>
+#include <sys/ioctl.h>
+#include <linux/fs.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
@@ -168,6 +170,51 @@ read_variable (efi_variable_t *var)
return EFI_SUCCESS;
}
+static int
+set_immutable_fd (int fd, int immutable)
+{
+ unsigned int flags;
+ int rc = 0;
+
+ rc = ioctl(fd, FS_IOC_GETFLAGS, &flags);
+ if (rc < 0) {
+ if (errno == ENOTTY)
+ rc = 0;
+ } else if ((immutable && !(flags & FS_IMMUTABLE_FL)) ||
+ (!immutable && (flags & FS_IMMUTABLE_FL))) {
+ if (immutable)
+ flags |= FS_IMMUTABLE_FL;
+ else
+ flags &= ~FS_IMMUTABLE_FL;
+
+ rc = ioctl(fd, FS_IOC_SETFLAGS, &flags);
+ }
+
+ return rc;
+}
+
+static int
+set_immutable (const char *filename, int immutable)
+{
+ typeof(errno) error = 0;
+ int fd;
+ int rc = 0;
+
+ fd = open(filename, O_RDONLY);
+ if (fd < 0) {
+ if (errno == ENOTTY)
+ return 0;
+ else
+ return fd;
+ }
+
+ rc = set_immutable_fd (fd, immutable);
+ error = errno;
+ close(fd);
+ errno = error;
+ return rc;
+}
+
efi_status_t
write_variable (const char *filename, efi_variable_t *var)
{
@@ -189,6 +236,9 @@ write_variable (const char *filename, efi_variable_t *var)
memcpy (buffer + sizeof(uint32_t), var->Data, var->DataSize);
total = var->DataSize + sizeof(uint32_t);
+ if (!access(filename, F_OK))
+ set_immutable (filename, 0);
+
flag = O_WRONLY | O_CREAT;
mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH;
fd = open (filename, flag, mode);
@@ -196,12 +246,14 @@ write_variable (const char *filename, efi_variable_t *var)
free (buffer);
return EFI_INVALID_PARAMETER;
}
+ set_immutable_fd (fd, 0);
writesize = write (fd, buffer, total);
if (writesize != total) {
close (fd);
free (buffer);
return EFI_INVALID_PARAMETER;
}
+ set_immutable_fd (fd, 1);
close (fd);
free (buffer);
return EFI_SUCCESS;
@@ -248,6 +300,7 @@ delete_variable(efi_variable_t *var)
snprintf(filename, PATH_MAX-1, "%s/%s", SYSFS_DIR_EFI_VARS, name);
+ set_immutable (filename, 0);
if (unlink (filename) == 0)
return EFI_SUCCESS;
@@ -270,8 +323,12 @@ edit_protected_variable (efi_variable_t *var)
if (ret != EFI_SUCCESS)
return ret;
- if (chmod (filename, S_IRUSR | S_IWUSR) < 0)
+ set_immutable (filename, 0);
+ if (chmod (filename, S_IRUSR | S_IWUSR) < 0) {
+ set_immutable (filename, 1);
return EFI_UNSUPPORTED;
+ }
+ set_immutable (filename, 1);
return EFI_SUCCESS;
}
--
2.8.4