Skip to content

Commit 36c6ff3

Browse files
committed
efivarfs: force RO when remounting if SetVariable is not supported
jira LE-1907 cve CVE-2023-52463 Rebuild_History Non-Buildable kernel-4.18.0-553.16.1.el8_10 commit-author Ilias Apalodimas <[email protected]> commit 0e8d244 Empty-Commit: Cherry-Pick Conflicts during history rebuild. Will be included in final tarball splat. Ref for failed cherry-pick at: ciq/ciq_backports/kernel-4.18.0-553.16.1.el8_10/0e8d2444.failed If SetVariable at runtime is not supported by the firmware we never assign a callback for that function. At the same time mount the efivarfs as RO so no one can call that. However, we never check the permission flags when someone remounts the filesystem as RW. As a result this leads to a crash looking like this: $ mount -o remount,rw /sys/firmware/efi/efivars $ efi-updatevar -f PK.auth PK [ 303.279166] Unable to handle kernel NULL pointer dereference at virtual address 0000000000000000 [ 303.280482] Mem abort info: [ 303.280854] ESR = 0x0000000086000004 [ 303.281338] EC = 0x21: IABT (current EL), IL = 32 bits [ 303.282016] SET = 0, FnV = 0 [ 303.282414] EA = 0, S1PTW = 0 [ 303.282821] FSC = 0x04: level 0 translation fault [ 303.283771] user pgtable: 4k pages, 48-bit VAs, pgdp=000000004258c000 [ 303.284913] [0000000000000000] pgd=0000000000000000, p4d=0000000000000000 [ 303.286076] Internal error: Oops: 0000000086000004 [#1] PREEMPT SMP [ 303.286936] Modules linked in: qrtr tpm_tis tpm_tis_core crct10dif_ce arm_smccc_trng rng_core drm fuse ip_tables x_tables ipv6 [ 303.288586] CPU: 1 PID: 755 Comm: efi-updatevar Not tainted 6.3.0-rc1-00108-gc7d0c4695c68 #1 [ 303.289748] Hardware name: Unknown Unknown Product/Unknown Product, BIOS 2023.04-00627-g88336918701d 04/01/2023 [ 303.291150] pstate: 60400005 (nZCv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--) [ 303.292123] pc : 0x0 [ 303.292443] lr : efivar_set_variable_locked+0x74/0xec [ 303.293156] sp : ffff800008673c10 [ 303.293619] x29: ffff800008673c10 x28: ffff0000037e8000 x27: 0000000000000000 [ 303.294592] x26: 0000000000000800 x25: ffff000002467400 x24: 0000000000000027 [ 303.295572] x23: ffffd49ea9832000 x22: ffff0000020c9800 x21: ffff000002467000 [ 303.296566] x20: 0000000000000001 x19: 00000000000007fc x18: 0000000000000000 [ 303.297531] x17: 0000000000000000 x16: 0000000000000000 x15: 0000aaaac807ab54 [ 303.298495] x14: ed37489f673633c0 x13: 71c45c606de13f80 x12: 47464259e219acf4 [ 303.299453] x11: ffff000002af7b01 x10: 0000000000000003 x9 : 0000000000000002 [ 303.300431] x8 : 0000000000000010 x7 : ffffd49ea8973230 x6 : 0000000000a85201 [ 303.301412] x5 : 0000000000000000 x4 : ffff0000020c9800 x3 : 00000000000007fc [ 303.302370] x2 : 0000000000000027 x1 : ffff000002467400 x0 : ffff000002467000 [ 303.303341] Call trace: [ 303.303679] 0x0 [ 303.303938] efivar_entry_set_get_size+0x98/0x16c [ 303.304585] efivarfs_file_write+0xd0/0x1a4 [ 303.305148] vfs_write+0xc4/0x2e4 [ 303.305601] ksys_write+0x70/0x104 [ 303.306073] __arm64_sys_write+0x1c/0x28 [ 303.306622] invoke_syscall+0x48/0x114 [ 303.307156] el0_svc_common.constprop.0+0x44/0xec [ 303.307803] do_el0_svc+0x38/0x98 [ 303.308268] el0_svc+0x2c/0x84 [ 303.308702] el0t_64_sync_handler+0xf4/0x120 [ 303.309293] el0t_64_sync+0x190/0x194 [ 303.309794] Code: ???????? ???????? ???????? ???????? (????????) [ 303.310612] ---[ end trace 0000000000000000 ]--- Fix this by adding a .reconfigure() function to the fs operations which we can use to check the requested flags and deny anything that's not RO if the firmware doesn't implement SetVariable at runtime. Fixes: f88814c ("efi/efivars: Expose RT service availability via efivars abstraction") Signed-off-by: Ilias Apalodimas <[email protected]> Signed-off-by: Ard Biesheuvel <[email protected]> (cherry picked from commit 0e8d244) Signed-off-by: Jonathan Maple <[email protected]> # Conflicts: # fs/efivarfs/super.c
1 parent 6fb0660 commit 36c6ff3

File tree

1 file changed

+116
-0
lines changed

1 file changed

+116
-0
lines changed
Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
efivarfs: force RO when remounting if SetVariable is not supported
2+
3+
jira LE-1907
4+
cve CVE-2023-52463
5+
Rebuild_History Non-Buildable kernel-4.18.0-553.16.1.el8_10
6+
commit-author Ilias Apalodimas <[email protected]>
7+
commit 0e8d2444168dd519fea501599d150e62718ed2fe
8+
Empty-Commit: Cherry-Pick Conflicts during history rebuild.
9+
Will be included in final tarball splat. Ref for failed cherry-pick at:
10+
ciq/ciq_backports/kernel-4.18.0-553.16.1.el8_10/0e8d2444.failed
11+
12+
If SetVariable at runtime is not supported by the firmware we never assign
13+
a callback for that function. At the same time mount the efivarfs as
14+
RO so no one can call that. However, we never check the permission flags
15+
when someone remounts the filesystem as RW. As a result this leads to a
16+
crash looking like this:
17+
18+
$ mount -o remount,rw /sys/firmware/efi/efivars
19+
$ efi-updatevar -f PK.auth PK
20+
21+
[ 303.279166] Unable to handle kernel NULL pointer dereference at virtual address 0000000000000000
22+
[ 303.280482] Mem abort info:
23+
[ 303.280854] ESR = 0x0000000086000004
24+
[ 303.281338] EC = 0x21: IABT (current EL), IL = 32 bits
25+
[ 303.282016] SET = 0, FnV = 0
26+
[ 303.282414] EA = 0, S1PTW = 0
27+
[ 303.282821] FSC = 0x04: level 0 translation fault
28+
[ 303.283771] user pgtable: 4k pages, 48-bit VAs, pgdp=000000004258c000
29+
[ 303.284913] [0000000000000000] pgd=0000000000000000, p4d=0000000000000000
30+
[ 303.286076] Internal error: Oops: 0000000086000004 [#1] PREEMPT SMP
31+
[ 303.286936] Modules linked in: qrtr tpm_tis tpm_tis_core crct10dif_ce arm_smccc_trng rng_core drm fuse ip_tables x_tables ipv6
32+
[ 303.288586] CPU: 1 PID: 755 Comm: efi-updatevar Not tainted 6.3.0-rc1-00108-gc7d0c4695c68 #1
33+
[ 303.289748] Hardware name: Unknown Unknown Product/Unknown Product, BIOS 2023.04-00627-g88336918701d 04/01/2023
34+
[ 303.291150] pstate: 60400005 (nZCv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--)
35+
[ 303.292123] pc : 0x0
36+
[ 303.292443] lr : efivar_set_variable_locked+0x74/0xec
37+
[ 303.293156] sp : ffff800008673c10
38+
[ 303.293619] x29: ffff800008673c10 x28: ffff0000037e8000 x27: 0000000000000000
39+
[ 303.294592] x26: 0000000000000800 x25: ffff000002467400 x24: 0000000000000027
40+
[ 303.295572] x23: ffffd49ea9832000 x22: ffff0000020c9800 x21: ffff000002467000
41+
[ 303.296566] x20: 0000000000000001 x19: 00000000000007fc x18: 0000000000000000
42+
[ 303.297531] x17: 0000000000000000 x16: 0000000000000000 x15: 0000aaaac807ab54
43+
[ 303.298495] x14: ed37489f673633c0 x13: 71c45c606de13f80 x12: 47464259e219acf4
44+
[ 303.299453] x11: ffff000002af7b01 x10: 0000000000000003 x9 : 0000000000000002
45+
[ 303.300431] x8 : 0000000000000010 x7 : ffffd49ea8973230 x6 : 0000000000a85201
46+
[ 303.301412] x5 : 0000000000000000 x4 : ffff0000020c9800 x3 : 00000000000007fc
47+
[ 303.302370] x2 : 0000000000000027 x1 : ffff000002467400 x0 : ffff000002467000
48+
[ 303.303341] Call trace:
49+
[ 303.303679] 0x0
50+
[ 303.303938] efivar_entry_set_get_size+0x98/0x16c
51+
[ 303.304585] efivarfs_file_write+0xd0/0x1a4
52+
[ 303.305148] vfs_write+0xc4/0x2e4
53+
[ 303.305601] ksys_write+0x70/0x104
54+
[ 303.306073] __arm64_sys_write+0x1c/0x28
55+
[ 303.306622] invoke_syscall+0x48/0x114
56+
[ 303.307156] el0_svc_common.constprop.0+0x44/0xec
57+
[ 303.307803] do_el0_svc+0x38/0x98
58+
[ 303.308268] el0_svc+0x2c/0x84
59+
[ 303.308702] el0t_64_sync_handler+0xf4/0x120
60+
[ 303.309293] el0t_64_sync+0x190/0x194
61+
[ 303.309794] Code: ???????? ???????? ???????? ???????? (????????)
62+
[ 303.310612] ---[ end trace 0000000000000000 ]---
63+
64+
Fix this by adding a .reconfigure() function to the fs operations which
65+
we can use to check the requested flags and deny anything that's not RO
66+
if the firmware doesn't implement SetVariable at runtime.
67+
68+
Fixes: f88814cc2578 ("efi/efivars: Expose RT service availability via efivars abstraction")
69+
Signed-off-by: Ilias Apalodimas <[email protected]>
70+
Signed-off-by: Ard Biesheuvel <[email protected]>
71+
(cherry picked from commit 0e8d2444168dd519fea501599d150e62718ed2fe)
72+
Signed-off-by: Jonathan Maple <[email protected]>
73+
74+
# Conflicts:
75+
# fs/efivarfs/super.c
76+
diff --cc fs/efivarfs/super.c
77+
index 25b2a651810b,869537f1a550..000000000000
78+
--- a/fs/efivarfs/super.c
79+
+++ b/fs/efivarfs/super.c
80+
@@@ -16,6 -14,8 +16,11 @@@
81+
#include <linux/ucs2_string.h>
82+
#include <linux/slab.h>
83+
#include <linux/magic.h>
84+
++<<<<<<< HEAD
85+
++=======
86+
+ #include <linux/statfs.h>
87+
+ #include <linux/printk.h>
88+
++>>>>>>> 0e8d2444168d (efivarfs: force RO when remounting if SetVariable is not supported)
89+
90+
#include "internal.h"
91+
92+
@@@ -231,8 -334,20 +236,23 @@@ static int efivarfs_get_tree(struct fs_
93+
return get_tree_single(fc, efivarfs_fill_super);
94+
}
95+
96+
+ static int efivarfs_reconfigure(struct fs_context *fc)
97+
+ {
98+
+ if (!efivar_supports_writes() && !(fc->sb_flags & SB_RDONLY)) {
99+
+ pr_err("Firmware does not support SetVariableRT. Can not remount with rw\n");
100+
+ return -EINVAL;
101+
+ }
102+
+
103+
+ return 0;
104+
+ }
105+
+
106+
static const struct fs_context_operations efivarfs_context_ops = {
107+
.get_tree = efivarfs_get_tree,
108+
++<<<<<<< HEAD
109+
++=======
110+
+ .parse_param = efivarfs_parse_param,
111+
+ .reconfigure = efivarfs_reconfigure,
112+
++>>>>>>> 0e8d2444168d (efivarfs: force RO when remounting if SetVariable is not supported)
113+
};
114+
115+
static int efivarfs_init_fs_context(struct fs_context *fc)
116+
* Unmerged path fs/efivarfs/super.c

0 commit comments

Comments
 (0)