[PATCH v2] fs/efivarfs: Permit read-only access on platforms that lack SetVariable

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Commit

  bf67fad19e493b ("efi: Use more granular check for availability for variable services")

introduced a check into the efivarfs init code that aborts loading of the
module if not all three variable runtime services (GetVariable, SetVariable
and GetNextVariable) are supported. However, this results in efivarfs being
unavailable entirely if only SetVariable support is missing, which is only
needed if you want to make any modifications.

So let's relax this restriction, and only require the GetVariable services,
but force efivarfs to be mounted read-only if SetVariable is unsupported.

Since efivarfs relies on the internal 'efivars' abstraction, we should
enable that as well for platforms that lack SetVariable support. However,
such SetVariable() calls will simply return EFI_UNSUPPORTED when issued,
and the efi-pstore and efivars sysfs driver perform their own checks for
supported services anyway.

Cc: Ilias Apalodimas <ilias.apalodimas@xxxxxxxxxx>
Fixes: bf67fad19e493b ("efi: Use more granular check for availability for variable services")
Reported-by: Heinrich Schuchardt <xypron.glpk@xxxxxx>
Signed-off-by: Ard Biesheuvel <ardb@xxxxxxxxxx>
---
v2: change efivars check as well

 drivers/firmware/efi/efi.c | 6 ++++--
 fs/efivarfs/super.c        | 6 +++++-
 2 files changed, 9 insertions(+), 3 deletions(-)

diff --git a/drivers/firmware/efi/efi.c b/drivers/firmware/efi/efi.c
index 5114cae4ec97..7b75efca0819 100644
--- a/drivers/firmware/efi/efi.c
+++ b/drivers/firmware/efi/efi.c
@@ -382,7 +382,8 @@ static int __init efisubsys_init(void)
 		return -ENOMEM;
 	}
 
-	if (efi_rt_services_supported(EFI_RT_SUPPORTED_VARIABLE_SERVICES)) {
+	if (efi_rt_services_supported(EFI_RT_SUPPORTED_GET_VARIABLE |
+				      EFI_RT_SUPPORTED_GET_NEXT_VARIABLE_NAME)) {
 		efivar_ssdt_load();
 		error = generic_ops_register();
 		if (error)
@@ -416,7 +417,8 @@ static int __init efisubsys_init(void)
 err_remove_group:
 	sysfs_remove_group(efi_kobj, &efi_subsys_attr_group);
 err_unregister:
-	if (efi_rt_services_supported(EFI_RT_SUPPORTED_VARIABLE_SERVICES))
+	if (efi_rt_services_supported(EFI_RT_SUPPORTED_GET_VARIABLE |
+				      EFI_RT_SUPPORTED_GET_NEXT_VARIABLE_NAME))
 		generic_ops_unregister();
 err_put:
 	kobject_put(efi_kobj);
diff --git a/fs/efivarfs/super.c b/fs/efivarfs/super.c
index 12c66f5d92dd..c12608f0dcd9 100644
--- a/fs/efivarfs/super.c
+++ b/fs/efivarfs/super.c
@@ -201,6 +201,9 @@ static int efivarfs_fill_super(struct super_block *sb, struct fs_context *fc)
 	sb->s_d_op		= &efivarfs_d_ops;
 	sb->s_time_gran         = 1;
 
+	if (!efi_rt_services_supported(EFI_RT_SUPPORTED_SET_VARIABLE))
+		sb->s_flags |= SB_RDONLY;
+
 	inode = efivarfs_get_inode(sb, NULL, S_IFDIR | 0755, 0, true);
 	if (!inode)
 		return -ENOMEM;
@@ -252,7 +255,8 @@ static struct file_system_type efivarfs_type = {
 
 static __init int efivarfs_init(void)
 {
-	if (!efi_rt_services_supported(EFI_RT_SUPPORTED_VARIABLE_SERVICES))
+	if (!efi_rt_services_supported(EFI_RT_SUPPORTED_GET_VARIABLE |
+				       EFI_RT_SUPPORTED_GET_NEXT_VARIABLE_NAME))
 		return -ENODEV;
 
 	if (!efivars_kobject())
-- 
2.17.1




[Index of Archives]     [Linux ARM Kernel]     [Linux ARM]     [Linux Omap]     [Fedora ARM]     [IETF Annouce]     [Security]     [Bugtraq]     [Linux OMAP]     [Linux MIPS]     [ECOS]     [Asterisk Internet PBX]     [Linux API]

  Powered by Linux