'modprobe efivars', when run in x64 OVMF EFI firmware in QEMU for x86 (i386) kernel, causes a NULL deref somewhere in restore_all_pax. pax-linux-3.4.7-test27-29-diff.patch interdiff was already applied (see bug #428726 and bug #430122).
Created attachment 321290 [details] NULL deref trace
Created attachment 321292 [details] linux-3.4.7-hardened.config
Created attachment 321294 [details, diff] pax-linux-3.4.7-test27-29-diff.patch
can you please upload efivars.ko and also move to the 3.5 series as we stopped supporting 3.4.
Created attachment 321358 [details] efivars.ko Attaching efivars.ko for hardened-sources-3.4.7. I will try with 3.5 later, but if you can't reproduce this bug with 3.5, then perhaps it's not worth investigating further? For some reason I assumed that this will be easy to reproduce.
(In reply to comment #5) > Attaching efivars.ko for hardened-sources-3.4.7. thanks, this is a null function ptr dereference in drivers/firmware/efivars.c:register_efivars: status = ops->get_next_variable(...) i wonder, does a vanilla kernel work? assuming it does, can you perhaps figure out which PaX feature causes this? i really don't see how this fptr can be null, it should have been initialized to virt_efi_get_next_variable. > I will try with 3.5 later, but if you can't reproduce this bug with 3.5[...] i didn't try it myself, i was and am still busy with other things, that's why i need feedback from you ;).
(In reply to comment #6) > i really don't see how this fptr > can be null, it should have been initialized to virt_efi_get_next_variable. Didn't check vanilla kernel yet, but doesn't the call proceed as: efivars_init -> kobject_create_and_add -> ... -> register_efivars where kobject_create_and_add is called before ops is initialized? That is, register_efivars is called implicitly via kobject_* before it is called explicitly in efivars_init. My understanding of kernel code is very limited, unfortunately.
(In reply to comment #7) > Didn't check vanilla kernel yet, but doesn't the call proceed as: > > efivars_init -> kobject_create_and_add -> ... -> register_efivars kobject_create_and_add doesn't call register_efivars, efivars_init itself does, after having initialized ops.
(In reply to comment #8) > kobject_create_and_add doesn't call register_efivars, efivars_init itself > does, after having initialized ops. But that's not what the trace shows, unless I misunderstand its meaning: Call Trace: [<e089a2da>] ? register_efivars+0xa4/0x22e [efivars] [<c192bccd>] ? kobject_add+0x66/0x70 [<c192be2f>] ? kobject_create_and_add+0x2d/0x5b [<e08a0000>] ? 0xe089ffff [<e08a0090>] ? efivars_init+0x90/0xe06 [efivars]
PS. Loading efivars from x64 OVMF works fine in i386 hardened-sources-3.4.2 (of course, there is no actual variables access afterwards, since 32-bit kernel to 64-bit firmware interface is not supported).
(In reply to comment #9) > But that's not what the trace shows, unless I misunderstand its meaning: On the other hand, this could be due to varargs use in kobject_* functions, which then means that efi.get_next_variable was NULL to begin with -- looking into it now.
I think it's a general kernel bug. /usr/src/linux/arch/x86/platform/efi/efi.c: #ifdef CONFIG_X86_32 [...] efi_native = !efi_64bit; #else [...] efi_native = efi_64bit; #endif void __init efi_enter_virtual_mode(void) [...] if (!efi_native) goto out; It is something that was added relatively recently, and wasn't present in 3.2 series: http://git.kernel.org/?p=linux/kernel/git/torvalds/linux.git;a=commitdiff;h=1adbfa3511ee1c1118e16a9a0246870f12fef4e6 Sorry -- I thought that the reason was another PaX-related incorrect image, since the NULL deref looked similar. Please reassign to the general kernel team. Thanks!
Bug reported upstream: https://bugzilla.kernel.org/show_bug.cgi?id=45991
(In reply to comment #9) > (In reply to comment #8) > > kobject_create_and_add doesn't call register_efivars, efivars_init itself > > does, after having initialized ops. > > But that's not what the trace shows, unless I misunderstand its meaning: kernel stacktraces are not that reliable (the dumper code prints out everything that could be interpreted as a code address, but it can't tell you when those addresses got on the stack or even if they are actual addresses), especially if you omit frame pointers as your config does ;).
Should be fixed in 3.7. Resolving as TEST-REQUEST as a reminder to myself once I install that branch, or in case anyone else feels like testing. :)
Fixed in 3.9.9-hardened.