2020-11-12 10:21:34

by Tobias Markus

[permalink] [raw]
Subject: Null pointer dereference in public key verification (related to SM2 introduction)

Hi,

running 5.10-rc3, I have come across a null pointer dereference.
It occured while trying to connect to a 802.1x/EAP-protected network using iwd.
However, the bug seems to be limited to iwd's usage of the keyctl API (unrelated to the wireless subsystem).

The bug seems related to the recent changes related to the SM2/SM3 algorithms, commits 215525639631a and 3093e7c16e12d.

I am including both the kernel logs as well as the system logs immediately before and after the null pointer dereference.
public_key_verify_signature+0x189 is crypto/asymmetric_keys/public_key.c:359, i.e.
if (strcmp(sig->pkey_algo, "sm2") == 0 && sig->data_size) {
[...]
Note that this block was introduced in commit 215525639631a.

kernel: wlan0: authenticate with <redacted>
kernel: wlan0: send auth to <redacted> (try 1/3)
kernel: wlan0: authenticated
kernel: wlan0: associate with <redacted> (try 1/3)
kernel: wlan0: RX AssocResp from <redacted> (capab=0x411 status=0 aid=24)
kernel: wlan0: associated
iwd[492]: EAP server tried method 52 while client was configured for method 25
kernel: BUG: kernel NULL pointer dereference, address: 0000000000000000
kernel: wlan0: Limiting TX power to 23 (23 - 0) dBm as advertised by <redacted>
kernel: #PF: supervisor read access in kernel mode
kernel: #PF: error_code(0x0000) - not-present page
kernel: PGD 0 P4D 0
kernel: Oops: 0000 [#1] PREEMPT SMP PTI
kernel: CPU: 1 PID: 492 Comm: iwd Tainted: G W T 5.10.0-rc3-custom #133
kernel: Hardware name: LENOVO 20HES01100/20HES01100, BIOS N1QET88W (1.63 ) 04/22/2020
kernel: RIP: 0010:public_key_verify_signature+0x189/0x3f0
kernel: Code: 48 8b 40 d0 44 89 c2 4c 89 fe 4c 89 e7 e8 4f 90 e7 00 85 c0 0f 85 67 01 00 00 48 8b 75 30 48 c7 c7 60 7d 85 9d >
kernel: RSP: 0018:ffff9fd6406ffd50 EFLAGS: 00010246
kernel: RAX: 0000000000000000 RBX: ffff8e1090272a40 RCX: 0000000000000004
kernel: RDX: ffff8e1082680400 RSI: 0000000000000000 RDI: ffffffff9d857d60
kernel: RBP: ffff9fd6406ffe88 R08: ffff8e10900ac820 R09: 0000000000000008
kernel: R10: 0000000000000000 R11: 000000000000010a R12: ffff8e1082681200
kernel: R13: ffff8e1082680900 R14: ffff9fd6406ffd88 R15: ffff8e10864df600
kernel: FS: 00007fbcb627e740(0000) GS:ffff8e13f2680000(0000) knlGS:0000000000000000
kernel: CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
kernel: CR2: 0000000000000000 CR3: 0000000110304005 CR4: 00000000003706e0
kernel: Call Trace:
kernel: asymmetric_key_verify_signature+0x5e/0x80
kernel: keyctl_pkey_verify+0xb6/0x110
kernel: do_syscall_64+0x33/0x40
kernel: entry_SYSCALL_64_after_hwframe+0x44/0xa9
kernel: RIP: 0033:0x7fbcb637bd5d
kernel: Code: 00 c3 66 2e 0f 1f 84 00 00 00 00 00 90 f3 0f 1e fa 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b >
kernel: RSP: 002b:00007ffd7e69d648 EFLAGS: 00000246 ORIG_RAX: 00000000000000fa
kernel: RAX: ffffffffffffffda RBX: 00007ffd7e69d6d0 RCX: 00007fbcb637bd5d
kernel: RDX: 000056210c5a3420 RSI: 00007ffd7e69d650 RDI: 000000000000001c
kernel: RBP: 000056210c5a3420 R08: 000056210c5a7a6d R09: 0000003024d797a1
kernel: R10: 00007ffd7e69d6d0 R11: 0000000000000246 R12: 000056210c5a7a6d
kernel: R13: 000056210c3b0b30 R14: 000056210c5a7a24 R15: 00007ffd7e69d6d0
kernel: Modules linked in: usblp
kernel: CR2: 0000000000000000
kernel: ---[ end trace ffdad8803dc4f4a6 ]---
kernel: RIP: 0010:public_key_verify_signature+0x189/0x3f0
kernel: Code: 48 8b 40 d0 44 89 c2 4c 89 fe 4c 89 e7 e8 4f 90 e7 00 85 c0 0f 85 67 01 00 00 48 8b 75 30 48 c7 c7 60 7d 85 9d >
kernel: RSP: 0018:ffff9fd6406ffd50 EFLAGS: 00010246
kernel: RAX: 0000000000000000 RBX: ffff8e1090272a40 RCX: 0000000000000004
kernel: RDX: ffff8e1082680400 RSI: 0000000000000000 RDI: ffffffff9d857d60
kernel: RBP: ffff9fd6406ffe88 R08: ffff8e10900ac820 R09: 0000000000000008
kernel: R10: 0000000000000000 R11: 000000000000010a R12: ffff8e1082681200
kernel: R13: ffff8e1082680900 R14: ffff9fd6406ffd88 R15: ffff8e10864df600
kernel: FS: 00007fbcb627e740(0000) GS:ffff8e13f2680000(0000) knlGS:0000000000000000
kernel: CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
kernel: CR2: 0000000000000000 CR3: 0000000110304005 CR4: 00000000003706e0
systemd[1]: iwd.service: Main process exited, code=killed, status=9/KILL
systemd[1]: iwd.service: Failed with result 'signal'.


Please advise if you need any further information.

Kind regards,
Tobias


2020-11-30 09:14:00

by David Howells

[permalink] [raw]
Subject: Re: Null pointer dereference in public key verification (related to SM2 introduction)

Tobias Markus <[email protected]> wrote:

> kernel: RIP: 0010:public_key_verify_signature+0x189/0x3f0

Is it possible for you to provide a disassembly of this function from the
kernel you were using? For this to occur on that line, it appears that sig
would need to be NULL - but that should trip an assertion at the top of the
function - or a very small number (which could be RCX, R09 or R11).

Thanks,
David

2020-12-02 12:39:23

by Tobias Markus

[permalink] [raw]
Subject: Re: Null pointer dereference in public key verification (related to SM2 introduction)

Hi David,

I'm afraid I can't provide an exactly matching disassembly of the function since I've since updated to newer -rc kernels.
Another debugging hurdle is that the specific kernel code path seems to be triggered by a very specific iwd code path that iwd only uses for 802.1X/EAP-secured networks, and I simply wasn't near any EAP-secured networks in the last few weeks.
I've tried creating a reproducer using a bash script calling various keyctl commands but to no success.

However, I can provide you a disassembly using my current -rc5 kernel that should correspond to the code path in question along with some observations.
Note that I inserted a BUG_ON right before the if statement for testing (that I couldn't get it to trigger yet since I wasn't near any EAP networks in the last weeks).
With the BUG_ON, lines 359-364 in crypto/asymmetric_keys/public_key.c look like this:
BUG_ON(!sig->pkey_algo);
if (strcmp(sig->pkey_algo, "sm2") == 0 && sig->data_size) {
ret = cert_sig_digest_update(sig, tfm);
if (ret)
goto error_free_key;
}

The relevant disassembly (I've attached the full disassembly):
<...>
359 BUG_ON(!sig->pkey_algo);
0xffffffff8158cee9 <+377>: mov 0x30(%rbp),%rsi
0xffffffff8158ceed <+381>: test %rsi,%rsi
0xffffffff8158cef0 <+384>: je 0xffffffff8158d11f <public_key_verify_signature+943>
0xffffffff8158d11f <+943>: ud2

360 if (strcmp(sig->pkey_algo, "sm2") == 0 && sig->data_size) {
0xffffffff8158cef6 <+390>: mov $0xffffffff82c427b0,%rdi
0xffffffff8158cefd <+397>: mov $0x4,%ecx
0xffffffff8158cf02 <+402>: repz cmpsb %es:(%rdi),%ds:(%rsi)
0xffffffff8158cf04 <+404>: seta %al
0xffffffff8158cf07 <+407>: sbb $0x0,%al
0xffffffff8158cf09 <+409>: test %al,%al
0xffffffff8158cf0b <+411>: jne 0xffffffff8158cf18 <public_key_verify_signature+424>
0xffffffff8158cf0d <+413>: mov 0x50(%rbp),%eax
0xffffffff8158cf10 <+416>: test %eax,%eax
0xffffffff8158cf12 <+418>: jne 0xffffffff8158d0df <public_key_verify_signature+879>
<...>

Some observations:
1. From the Oops report, rsi was zero and seems to be the source of the null pointer.
2. Interpreting the BUG_ON disassembly, rsi is apparently set to sig->pkey_algo.
3. If I recall correctly from the analysis I did right after the Oops, public_key_verify_signature+402 should be the instruction that triggered the Oops. It corresponds to the strcmp.

In conclusion, my hypothesis would be that for some reason sig->pkey_algo is a null pointer.
This seems plausible since the strcmp would be the first line to actually touch sig->pkey_algo in that function.
Take all this with a grain of salt because in theory GCC could have shuffled stuff around since I introduced the BUG_ON.

I would love to debug this further, but I'm in dire need of a simpler test case (other than finding another EAP-secured network). If you or anyone could point me to a simple program that uses the public key infrastructure, it might be easier to trigger the Oops again.

Kind Regards,
Tobias

David Howells wrote:
> Tobias Markus <[email protected]> wrote:
>
>> kernel: RIP: 0010:public_key_verify_signature+0x189/0x3f0
>
> Is it possible for you to provide a disassembly of this function from the
> kernel you were using? For this to occur on that line, it appears that sig
> would need to be NULL - but that should trip an assertion at the top of the
> function - or a very small number (which could be RCX, R09 or R11).
>
> Thanks,
> David
>


Attachments:
disassembly.txt (26.58 kB)

2021-01-07 07:48:13

by Tee Hao Wei

[permalink] [raw]
Subject: Re: Null pointer dereference in public key verification (related to SM2 introduction)

On 2/12/20 8:24 pm, Tobias Markus wrote:
> Hi David,
>
> I'm afraid I can't provide an exactly matching disassembly of the function since I've since updated to newer -rc kernels.
> Another debugging hurdle is that the specific kernel code path seems to be triggered by a very specific iwd code path that iwd only uses for 802.1X/EAP-secured networks, and I simply wasn't near any EAP-secured networks in the last few weeks.
> I've tried creating a reproducer using a bash script calling various keyctl commands but to no success>
> David Howells wrote:
>> Tobias Markus <[email protected]> wrote:
>>
>>> kernel: RIP: 0010:public_key_verify_signature+0x189/0x3f0
>>
>> Is it possible for you to provide a disassembly of this function from the
>> kernel you were using? For this to occur on that line, it appears that sig
>> would need to be NULL - but that should trip an assertion at the top of the
>> function - or a very small number (which could be RCX, R09 or R11).
>>
>> Thanks,
>> David
>>

This problem is still in 5.10.4 (with iwd 1.10):

---
kernel: BUG: kernel NULL pointer dereference, address: 0000000000000000
kernel: #PF: supervisor read access in kernel mode
kernel: #PF: error_code(0x0000) - not-present page
kernel: PGD 0 P4D 0
kernel: Oops: 0000 [#6] PREEMPT SMP PTI
kernel: CPU: 7 PID: 6089 Comm: iwd Tainted: G S UD W OE 5.10.4-arch2-1 #1
kernel: Hardware name: LENOVO 20L7CTO1WW/20L7CTO1WW, BIOS N22ET60P (1.37 ) 11/25/2019
kernel: RIP: 0010:public_key_verify_signature+0x189/0x400
kernel: Code: 48 8b 40 d0 44 89 ca 4c 89 fe 4c 89 e7 e8 ef 33 9b 00 85 c0 0f 85 80 01 00 00 48 8b 75 30 48 c7 c7 f8 84 99 ba b9 04 00 00 00 <f3> a6 0f 97 c0 1c 00 84 c0 75 0b 8b 45 50 85 c0 0f 85 e0 01 00 00
kernel: RSP: 0018:ffffaf6d811b3d50 EFLAGS: 00010246
kernel: RAX: 0000000000000000 RBX: ffff99d6a24ba540 RCX: 0000000000000004
kernel: RDX: ffff99d6a2436c00 RSI: 0000000000000000 RDI: ffffffffba9984f8
kernel: RBP: ffffaf6d811b3e88 R08: ffff99d681b58cc0 R09: 0000000000000008
kernel: R10: 0000000000000000 R11: 000000000000000a R12: ffff99d6a24bab40
kernel: R13: ffff99d6a2437200 R14: ffffaf6d811b3d88 R15: ffff99d5ce134800
kernel: FS: 00007f14d1578740(0000) GS:ffff99dac75c0000(0000) knlGS:0000000000000000
kernel: CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
kernel: CR2: 0000000000000000 CR3: 00000001e26aa005 CR4: 00000000003706e0
kernel: Call Trace:
kernel: asymmetric_key_verify_signature+0x5e/0x80
kernel: keyctl_pkey_verify+0xc0/0x120
kernel: do_syscall_64+0x33/0x40
kernel: entry_SYSCALL_64_after_hwframe+0x44/0xa9
kernel: RIP: 0033:0x7f14d1675d5d
kernel: Code: 00 c3 66 2e 0f 1f 84 00 00 00 00 00 90 f3 0f 1e fa 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 8b 0d e3 70 0c 00 f7 d8 64 89 01 48
kernel: RSP: 002b:00007ffce76da728 EFLAGS: 00000246 ORIG_RAX: 00000000000000fa
kernel: RAX: ffffffffffffffda RBX: 00007ffce76da7b0 RCX: 00007f14d1675d5d
kernel: RDX: 0000565457d08ac0 RSI: 00007ffce76da730 RDI: 000000000000001c
kernel: RBP: 0000565457d08ac0 R08: 0000565457d0b2dd R09: 000000303ec2c07a
kernel: R10: 00007ffce76da7b0 R11: 0000000000000246 R12: 0000565457d0b2dd
kernel: R13: 00007f14d177d9c0 R14: 0000565457d0b294 R15: 00007ffce76da7b0
kernel: Modules linked in: bnep uvcvideo videobuf2_vmalloc videobuf2_memops videobuf2_v4l2 videobuf2_common videodev mc ccm algif_aead des_generic libdes ecb algif_skcipher cmac md4 algif_hash af_alg btusb btrtl btbcm btintel bluetooth snd_soc_skl elan_i2c snd_hda_codec_hdmi snd_soc_sst_ipc snd_soc_sst_dsp ecdh_generic ecc iTCO_wdt snd_hda_ext_core iwlmvm intel_pmc_bxt snd_soc_acpi_intel_match mei_hdcp ee1004 iTCO_vendor_support snd_hda_codec_realtek snd_soc_acpi wmi_bmof intel_wmi_thunderbolt snd_hda_codec_generic intel_rapl_msr snd_hda_intel mac80211 snd_intel_dspcfg soundwire_intel soundwire_generic_allocation soundwire_cadence snd_hda_codec x86_pkg_temp_thermal intel_powerclamp coretemp libarc4 snd_hda_core kvm_intel snd_hwdep nls_iso8859_1 soundwire_bus vfat fat kvm snd_soc_core iwlwifi snd_compress irqbypass rapl ac97_bus intel_cstate snd_pcm_dmaengine intel_uncore joydev snd_pcm cfg80211 mousedev mei_me pcspkr e1000e i2c_i801 snd_timer i2c_smbus mei processor_thermal_device
kernel: intel_xhci_usb_role_switch intel_rapl_common intel_pch_thermal roles intel_soc_dts_iosf thinkpad_acpi wmi ledtrig_audio rfkill snd int3403_thermal soundcore int340x_thermal_zone int3400_thermal acpi_thermal_rel acpi_pad mac_hid pkcs8_key_parser crypto_user fuse acpi_call(OE) bpf_preload ip_tables x_tables ext4 crc32c_generic crc16 mbcache jbd2 uas usb_storage dm_crypt cbc encrypted_keys dm_mod trusted tpm rng_core crct10dif_pclmul crc32_pclmul crc32c_intel ghash_clmulni_intel aesni_intel crypto_simd cryptd glue_helper serio_raw xhci_pci xhci_pci_renesas i915 video intel_gtt i2c_algo_bit drm_kms_helper syscopyarea sysfillrect sysimgblt fb_sys_fops cec drm agpgart
kernel: CR2: 0000000000000000
kernel: ---[ end trace fcbb482b549250b6 ]---
kernel: RIP: 0010:public_key_verify_signature+0x189/0x400
kernel: Code: 48 8b 40 d0 44 89 ca 4c 89 fe 4c 89 e7 e8 ef 33 9b 00 85 c0 0f 85 80 01 00 00 48 8b 75 30 48 c7 c7 f8 84 99 ba b9 04 00 00 00 <f3> a6 0f 97 c0 1c 00 84 c0 75 0b 8b 45 50 85 c0 0f 85 e0 01 00 00
kernel: RSP: 0018:ffffaf6d80ad7d50 EFLAGS: 00010246
kernel: RAX: 0000000000000000 RBX: ffff99d61f5611c0 RCX: 0000000000000004
kernel: RDX: ffff99d66714cb00 RSI: 0000000000000000 RDI: ffffffffba9984f8
kernel: RBP: ffffaf6d80ad7e88 R08: ffff99d5c60fe760 R09: 0000000000000008
kernel: R10: 0000000000000000 R11: 000000000000000a R12: ffff99d5e97afec0
kernel: R13: ffff99d66714d600 R14: ffffaf6d80ad7d88 R15: ffff99d5c6e90a00
kernel: FS: 00007f14d1578740(0000) GS:ffff99dac75c0000(0000) knlGS:0000000000000000
kernel: CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
kernel: CR2: 0000000000000000 CR3: 00000001e26aa005 CR4: 00000000003706e0
systemd[1]: iwd.service: Main process exited, code=killed, status=9/KILL
systemd[1]: iwd.service: Failed with result 'signal'.
---

Here is the disassembly of public_key_verify_signature around the faulting instruction

---
0xffffffffb9a4eaf9: mov 0x30(%rbp),%rsi
0xffffffffb9a4eafd: mov $0xffffffffba9984f8,%rdi
0xffffffffb9a4eb04: mov $0x4,%ecx
0xffffffffb9a4eb09: repz cmpsb %es:(%rdi),%ds:(%rsi) # fault here
0xffffffffb9a4eb0b: seta %al
0xffffffffb9a4eb0e: sbb $0x0,%al
0xffffffffb9a4eb10: test %al,%al
0xffffffffb9a4eb12: jne 0xffffffffb9a4eb1f
0xffffffffb9a4eb14: mov 0x50(%rbp),%eax
0xffffffffb9a4eb17: test %eax,%eax
0xffffffffb9a4eb19: jne 0xffffffffb9a4ecff
---

corresponding to this: https://elixir.bootlin.com/linux/v5.10.4/source/crypto/asymmetric_keys/public_key.c#L359

---
if (strcmp(sig->pkey_algo, "sm2") == 0 && sig->data_size) {
ret = cert_sig_digest_update(sig, tfm);
if (ret)
goto error_free_key;
}
---

So it seems like sig->pkey_algo is null. I will try to debug, but I don't get access to an EAP-protected network often (maybe once or twice a week), so it might take a while.

--
Hao Wei

2021-01-07 07:59:35

by Tianjia Zhang

[permalink] [raw]
Subject: Re: Null pointer dereference in public key verification (related to SM2 introduction)

Hi,

Sorry, I just read this email. I will submit the fix patch as soon as
possible. Thanks for reporting.

Best regards,
Tianjia


On 1/7/21 3:27 PM, Tee Hao Wei wrote:
> On 2/12/20 8:24 pm, Tobias Markus wrote:
>> Hi David,
>>
>> I'm afraid I can't provide an exactly matching disassembly of the function since I've since updated to newer -rc kernels.
>> Another debugging hurdle is that the specific kernel code path seems to be triggered by a very specific iwd code path that iwd only uses for 802.1X/EAP-secured networks, and I simply wasn't near any EAP-secured networks in the last few weeks.
>> I've tried creating a reproducer using a bash script calling various keyctl commands but to no success>
>> David Howells wrote:
>>> Tobias Markus <[email protected]> wrote:
>>>
>>>> kernel: RIP: 0010:public_key_verify_signature+0x189/0x3f0
>>>
>>> Is it possible for you to provide a disassembly of this function from the
>>> kernel you were using? For this to occur on that line, it appears that sig
>>> would need to be NULL - but that should trip an assertion at the top of the
>>> function - or a very small number (which could be RCX, R09 or R11).
>>>
>>> Thanks,
>>> David
>>>
>
> This problem is still in 5.10.4 (with iwd 1.10):
>
> ---
> kernel: BUG: kernel NULL pointer dereference, address: 0000000000000000
> kernel: #PF: supervisor read access in kernel mode
> kernel: #PF: error_code(0x0000) - not-present page
> kernel: PGD 0 P4D 0
> kernel: Oops: 0000 [#6] PREEMPT SMP PTI
> kernel: CPU: 7 PID: 6089 Comm: iwd Tainted: G S UD W OE 5.10.4-arch2-1 #1
> kernel: Hardware name: LENOVO 20L7CTO1WW/20L7CTO1WW, BIOS N22ET60P (1.37 ) 11/25/2019
> kernel: RIP: 0010:public_key_verify_signature+0x189/0x400
> kernel: Code: 48 8b 40 d0 44 89 ca 4c 89 fe 4c 89 e7 e8 ef 33 9b 00 85 c0 0f 85 80 01 00 00 48 8b 75 30 48 c7 c7 f8 84 99 ba b9 04 00 00 00 <f3> a6 0f 97 c0 1c 00 84 c0 75 0b 8b 45 50 85 c0 0f 85 e0 01 00 00
> kernel: RSP: 0018:ffffaf6d811b3d50 EFLAGS: 00010246
> kernel: RAX: 0000000000000000 RBX: ffff99d6a24ba540 RCX: 0000000000000004
> kernel: RDX: ffff99d6a2436c00 RSI: 0000000000000000 RDI: ffffffffba9984f8
> kernel: RBP: ffffaf6d811b3e88 R08: ffff99d681b58cc0 R09: 0000000000000008
> kernel: R10: 0000000000000000 R11: 000000000000000a R12: ffff99d6a24bab40
> kernel: R13: ffff99d6a2437200 R14: ffffaf6d811b3d88 R15: ffff99d5ce134800
> kernel: FS: 00007f14d1578740(0000) GS:ffff99dac75c0000(0000) knlGS:0000000000000000
> kernel: CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
> kernel: CR2: 0000000000000000 CR3: 00000001e26aa005 CR4: 00000000003706e0
> kernel: Call Trace:
> kernel: asymmetric_key_verify_signature+0x5e/0x80
> kernel: keyctl_pkey_verify+0xc0/0x120
> kernel: do_syscall_64+0x33/0x40
> kernel: entry_SYSCALL_64_after_hwframe+0x44/0xa9
> kernel: RIP: 0033:0x7f14d1675d5d
> kernel: Code: 00 c3 66 2e 0f 1f 84 00 00 00 00 00 90 f3 0f 1e fa 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 8b 0d e3 70 0c 00 f7 d8 64 89 01 48
> kernel: RSP: 002b:00007ffce76da728 EFLAGS: 00000246 ORIG_RAX: 00000000000000fa
> kernel: RAX: ffffffffffffffda RBX: 00007ffce76da7b0 RCX: 00007f14d1675d5d
> kernel: RDX: 0000565457d08ac0 RSI: 00007ffce76da730 RDI: 000000000000001c
> kernel: RBP: 0000565457d08ac0 R08: 0000565457d0b2dd R09: 000000303ec2c07a
> kernel: R10: 00007ffce76da7b0 R11: 0000000000000246 R12: 0000565457d0b2dd
> kernel: R13: 00007f14d177d9c0 R14: 0000565457d0b294 R15: 00007ffce76da7b0
> kernel: Modules linked in: bnep uvcvideo videobuf2_vmalloc videobuf2_memops videobuf2_v4l2 videobuf2_common videodev mc ccm algif_aead des_generic libdes ecb algif_skcipher cmac md4 algif_hash af_alg btusb btrtl btbcm btintel bluetooth snd_soc_skl elan_i2c snd_hda_codec_hdmi snd_soc_sst_ipc snd_soc_sst_dsp ecdh_generic ecc iTCO_wdt snd_hda_ext_core iwlmvm intel_pmc_bxt snd_soc_acpi_intel_match mei_hdcp ee1004 iTCO_vendor_support snd_hda_codec_realtek snd_soc_acpi wmi_bmof intel_wmi_thunderbolt snd_hda_codec_generic intel_rapl_msr snd_hda_intel mac80211 snd_intel_dspcfg soundwire_intel soundwire_generic_allocation soundwire_cadence snd_hda_codec x86_pkg_temp_thermal intel_powerclamp coretemp libarc4 snd_hda_core kvm_intel snd_hwdep nls_iso8859_1 soundwire_bus vfat fat kvm snd_soc_core iwlwifi snd_compress irqbypass rapl ac97_bus intel_cstate snd_pcm_dmaengine intel_uncore joydev snd_pcm cfg80211 mousedev mei_me pcspkr e1000e i2c_i801 snd_timer i2c_smbus mei processor_thermal_device
> kernel: intel_xhci_usb_role_switch intel_rapl_common intel_pch_thermal roles intel_soc_dts_iosf thinkpad_acpi wmi ledtrig_audio rfkill snd int3403_thermal soundcore int340x_thermal_zone int3400_thermal acpi_thermal_rel acpi_pad mac_hid pkcs8_key_parser crypto_user fuse acpi_call(OE) bpf_preload ip_tables x_tables ext4 crc32c_generic crc16 mbcache jbd2 uas usb_storage dm_crypt cbc encrypted_keys dm_mod trusted tpm rng_core crct10dif_pclmul crc32_pclmul crc32c_intel ghash_clmulni_intel aesni_intel crypto_simd cryptd glue_helper serio_raw xhci_pci xhci_pci_renesas i915 video intel_gtt i2c_algo_bit drm_kms_helper syscopyarea sysfillrect sysimgblt fb_sys_fops cec drm agpgart
> kernel: CR2: 0000000000000000
> kernel: ---[ end trace fcbb482b549250b6 ]---
> kernel: RIP: 0010:public_key_verify_signature+0x189/0x400
> kernel: Code: 48 8b 40 d0 44 89 ca 4c 89 fe 4c 89 e7 e8 ef 33 9b 00 85 c0 0f 85 80 01 00 00 48 8b 75 30 48 c7 c7 f8 84 99 ba b9 04 00 00 00 <f3> a6 0f 97 c0 1c 00 84 c0 75 0b 8b 45 50 85 c0 0f 85 e0 01 00 00
> kernel: RSP: 0018:ffffaf6d80ad7d50 EFLAGS: 00010246
> kernel: RAX: 0000000000000000 RBX: ffff99d61f5611c0 RCX: 0000000000000004
> kernel: RDX: ffff99d66714cb00 RSI: 0000000000000000 RDI: ffffffffba9984f8
> kernel: RBP: ffffaf6d80ad7e88 R08: ffff99d5c60fe760 R09: 0000000000000008
> kernel: R10: 0000000000000000 R11: 000000000000000a R12: ffff99d5e97afec0
> kernel: R13: ffff99d66714d600 R14: ffffaf6d80ad7d88 R15: ffff99d5c6e90a00
> kernel: FS: 00007f14d1578740(0000) GS:ffff99dac75c0000(0000) knlGS:0000000000000000
> kernel: CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
> kernel: CR2: 0000000000000000 CR3: 00000001e26aa005 CR4: 00000000003706e0
> systemd[1]: iwd.service: Main process exited, code=killed, status=9/KILL
> systemd[1]: iwd.service: Failed with result 'signal'.
> ---
>
> Here is the disassembly of public_key_verify_signature around the faulting instruction
>
> ---
> 0xffffffffb9a4eaf9: mov 0x30(%rbp),%rsi
> 0xffffffffb9a4eafd: mov $0xffffffffba9984f8,%rdi
> 0xffffffffb9a4eb04: mov $0x4,%ecx
> 0xffffffffb9a4eb09: repz cmpsb %es:(%rdi),%ds:(%rsi) # fault here
> 0xffffffffb9a4eb0b: seta %al
> 0xffffffffb9a4eb0e: sbb $0x0,%al
> 0xffffffffb9a4eb10: test %al,%al
> 0xffffffffb9a4eb12: jne 0xffffffffb9a4eb1f
> 0xffffffffb9a4eb14: mov 0x50(%rbp),%eax
> 0xffffffffb9a4eb17: test %eax,%eax
> 0xffffffffb9a4eb19: jne 0xffffffffb9a4ecff
> ---
>
> corresponding to this: https://elixir.bootlin.com/linux/v5.10.4/source/crypto/asymmetric_keys/public_key.c#L359
>
> ---
> if (strcmp(sig->pkey_algo, "sm2") == 0 && sig->data_size) {
> ret = cert_sig_digest_update(sig, tfm);
> if (ret)
> goto error_free_key;
> }
> ---
>
> So it seems like sig->pkey_algo is null. I will try to debug, but I don't get access to an EAP-protected network often (maybe once or twice a week), so it might take a while.
>

2021-01-07 08:52:10

by Jean-Louis Dupond

[permalink] [raw]
Subject: Re: Null pointer dereference in public key verification (related to SM2 introduction)

Hi,

I've hit this bug also when trying to connect to my office Wifi via IWD.

The pkey_algo is indeed NULL/uninitialized:
As we create the sig here:
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/tree/crypto/asymmetric_keys/asymmetric_type.c?h=v5.10.5&id=215525639631ade1d67e879fe2c3d7195daa9f59#n565
But as no value is assigned to pkey_algo, we do a strcmp on something
undefined.

Please submit a fix as soon as possible :) as connecting to office wifi
is now broken.

Thanks
Jean-Louis

On 7/01/2021 08:58, Tianjia Zhang wrote:
> Hi,
>
> Sorry, I just read this email. I will submit the fix patch as soon as
> possible. Thanks for reporting.
>
> Best regards,
> Tianjia
>
>
> On 1/7/21 3:27 PM, Tee Hao Wei wrote:
>> On 2/12/20 8:24 pm, Tobias Markus wrote:
>>> Hi David,
>>>
>>> I'm afraid I can't provide an exactly matching disassembly of the
>>> function since I've since updated to newer -rc kernels.
>>> Another debugging hurdle is that the specific kernel code path seems
>>> to be triggered by a very specific iwd code path that iwd only uses
>>> for 802.1X/EAP-secured networks, and I simply wasn't near any
>>> EAP-secured networks in the last few weeks.
>>> I've tried creating a reproducer using a bash script calling various
>>> keyctl commands but to no success>
>>> David Howells wrote:
>>>> Tobias Markus <[email protected]> wrote:
>>>>
>>>>> kernel: RIP: 0010:public_key_verify_signature+0x189/0x3f0
>>>>
>>>> Is it possible for you to provide a disassembly of this function
>>>> from the
>>>> kernel you were using?  For this to occur on that line, it appears
>>>> that sig
>>>> would need to be NULL - but that should trip an assertion at the
>>>> top of the
>>>> function - or a very small number (which could be RCX, R09 or R11).
>>>>
>>>> Thanks,
>>>> David
>>>>
>>
>> This problem is still in 5.10.4 (with iwd 1.10):
>>
>> ---
>> kernel: BUG: kernel NULL pointer dereference, address: 0000000000000000
>> kernel: #PF: supervisor read access in kernel mode
>> kernel: #PF: error_code(0x0000) - not-present page
>> kernel: PGD 0 P4D 0
>> kernel: Oops: 0000 [#6] PREEMPT SMP PTI
>> kernel: CPU: 7 PID: 6089 Comm: iwd Tainted: G S   UD W  OE
>> 5.10.4-arch2-1 #1
>> kernel: Hardware name: LENOVO 20L7CTO1WW/20L7CTO1WW, BIOS N22ET60P
>> (1.37 ) 11/25/2019
>> kernel: RIP: 0010:public_key_verify_signature+0x189/0x400
>> kernel: Code: 48 8b 40 d0 44 89 ca 4c 89 fe 4c 89 e7 e8 ef 33 9b 00
>> 85 c0 0f 85 80 01 00 00 48 8b 75 30 48 c7 c7 f8 84 99 ba b9 04 00 00
>> 00 <f3> a6 0f 97 c0 1c 00 84 c0 75 0b 8b 45 50 85 c0 0f 85 e0 01 00 00
>> kernel: RSP: 0018:ffffaf6d811b3d50 EFLAGS: 00010246
>> kernel: RAX: 0000000000000000 RBX: ffff99d6a24ba540 RCX:
>> 0000000000000004
>> kernel: RDX: ffff99d6a2436c00 RSI: 0000000000000000 RDI:
>> ffffffffba9984f8
>> kernel: RBP: ffffaf6d811b3e88 R08: ffff99d681b58cc0 R09:
>> 0000000000000008
>> kernel: R10: 0000000000000000 R11: 000000000000000a R12:
>> ffff99d6a24bab40
>> kernel: R13: ffff99d6a2437200 R14: ffffaf6d811b3d88 R15:
>> ffff99d5ce134800
>> kernel: FS:  00007f14d1578740(0000) GS:ffff99dac75c0000(0000)
>> knlGS:0000000000000000
>> kernel: CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
>> kernel: CR2: 0000000000000000 CR3: 00000001e26aa005 CR4:
>> 00000000003706e0
>> kernel: Call Trace:
>> kernel:  asymmetric_key_verify_signature+0x5e/0x80
>> kernel:  keyctl_pkey_verify+0xc0/0x120
>> kernel:  do_syscall_64+0x33/0x40
>> kernel:  entry_SYSCALL_64_after_hwframe+0x44/0xa9
>> kernel: RIP: 0033:0x7f14d1675d5d
>> kernel: Code: 00 c3 66 2e 0f 1f 84 00 00 00 00 00 90 f3 0f 1e fa 48
>> 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f
>> 05 <48> 3d 01 f0 ff ff 73 01 c3 48 8b 0d e3 70 0c 00 f7 d8 64 89 01 48
>> kernel: RSP: 002b:00007ffce76da728 EFLAGS: 00000246 ORIG_RAX:
>> 00000000000000fa
>> kernel: RAX: ffffffffffffffda RBX: 00007ffce76da7b0 RCX:
>> 00007f14d1675d5d
>> kernel: RDX: 0000565457d08ac0 RSI: 00007ffce76da730 RDI:
>> 000000000000001c
>> kernel: RBP: 0000565457d08ac0 R08: 0000565457d0b2dd R09:
>> 000000303ec2c07a
>> kernel: R10: 00007ffce76da7b0 R11: 0000000000000246 R12:
>> 0000565457d0b2dd
>> kernel: R13: 00007f14d177d9c0 R14: 0000565457d0b294 R15:
>> 00007ffce76da7b0
>> kernel: Modules linked in: bnep uvcvideo videobuf2_vmalloc
>> videobuf2_memops videobuf2_v4l2 videobuf2_common videodev mc ccm
>> algif_aead des_generic libdes ecb algif_skcipher cmac md4 algif_hash
>> af_alg btusb btrtl btbcm btintel bluetooth snd_soc_skl elan_i2c
>> snd_hda_codec_hdmi snd_soc_sst_ipc snd_soc_sst_dsp ecdh_generic ecc
>> iTCO_wdt snd_hda_ext_core iwlmvm intel_pmc_bxt
>> snd_soc_acpi_intel_match mei_hdcp ee1004 iTCO_vendor_support
>> snd_hda_codec_realtek snd_soc_acpi wmi_bmof intel_wmi_thunderbolt
>> snd_hda_codec_generic intel_rapl_msr snd_hda_intel mac80211
>> snd_intel_dspcfg soundwire_intel soundwire_generic_allocation
>> soundwire_cadence snd_hda_codec x86_pkg_temp_thermal intel_powerclamp
>> coretemp libarc4 snd_hda_core kvm_intel snd_hwdep nls_iso8859_1
>> soundwire_bus vfat fat kvm snd_soc_core iwlwifi snd_compress
>> irqbypass rapl ac97_bus intel_cstate snd_pcm_dmaengine intel_uncore
>> joydev snd_pcm cfg80211 mousedev mei_me pcspkr e1000e i2c_i801
>> snd_timer i2c_smbus mei processor_thermal_device
>> kernel:  intel_xhci_usb_role_switch intel_rapl_common
>> intel_pch_thermal roles intel_soc_dts_iosf thinkpad_acpi wmi
>> ledtrig_audio rfkill snd int3403_thermal soundcore
>> int340x_thermal_zone int3400_thermal acpi_thermal_rel acpi_pad
>> mac_hid pkcs8_key_parser crypto_user fuse acpi_call(OE) bpf_preload
>> ip_tables x_tables ext4 crc32c_generic crc16 mbcache jbd2 uas
>> usb_storage dm_crypt cbc encrypted_keys dm_mod trusted tpm rng_core
>> crct10dif_pclmul crc32_pclmul crc32c_intel ghash_clmulni_intel
>> aesni_intel crypto_simd cryptd glue_helper serio_raw xhci_pci
>> xhci_pci_renesas i915 video intel_gtt i2c_algo_bit drm_kms_helper
>> syscopyarea sysfillrect sysimgblt fb_sys_fops cec drm agpgart
>> kernel: CR2: 0000000000000000
>> kernel: ---[ end trace fcbb482b549250b6 ]---
>> kernel: RIP: 0010:public_key_verify_signature+0x189/0x400
>> kernel: Code: 48 8b 40 d0 44 89 ca 4c 89 fe 4c 89 e7 e8 ef 33 9b 00
>> 85 c0 0f 85 80 01 00 00 48 8b 75 30 48 c7 c7 f8 84 99 ba b9 04 00 00
>> 00 <f3> a6 0f 97 c0 1c 00 84 c0 75 0b 8b 45 50 85 c0 0f 85 e0 01 00 00
>> kernel: RSP: 0018:ffffaf6d80ad7d50 EFLAGS: 00010246
>> kernel: RAX: 0000000000000000 RBX: ffff99d61f5611c0 RCX:
>> 0000000000000004
>> kernel: RDX: ffff99d66714cb00 RSI: 0000000000000000 RDI:
>> ffffffffba9984f8
>> kernel: RBP: ffffaf6d80ad7e88 R08: ffff99d5c60fe760 R09:
>> 0000000000000008
>> kernel: R10: 0000000000000000 R11: 000000000000000a R12:
>> ffff99d5e97afec0
>> kernel: R13: ffff99d66714d600 R14: ffffaf6d80ad7d88 R15:
>> ffff99d5c6e90a00
>> kernel: FS:  00007f14d1578740(0000) GS:ffff99dac75c0000(0000)
>> knlGS:0000000000000000
>> kernel: CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
>> kernel: CR2: 0000000000000000 CR3: 00000001e26aa005 CR4:
>> 00000000003706e0
>> systemd[1]: iwd.service: Main process exited, code=killed, status=9/KILL
>> systemd[1]: iwd.service: Failed with result 'signal'.
>> ---
>>
>> Here is the disassembly of public_key_verify_signature around the
>> faulting instruction
>>
>> ---
>>     0xffffffffb9a4eaf9:    mov    0x30(%rbp),%rsi
>>     0xffffffffb9a4eafd:    mov    $0xffffffffba9984f8,%rdi
>>     0xffffffffb9a4eb04:    mov    $0x4,%ecx
>>     0xffffffffb9a4eb09:    repz cmpsb %es:(%rdi),%ds:(%rsi) # fault here
>>     0xffffffffb9a4eb0b:    seta   %al
>>     0xffffffffb9a4eb0e:    sbb    $0x0,%al
>>     0xffffffffb9a4eb10:    test   %al,%al
>>     0xffffffffb9a4eb12:    jne    0xffffffffb9a4eb1f
>>     0xffffffffb9a4eb14:    mov    0x50(%rbp),%eax
>>     0xffffffffb9a4eb17:    test   %eax,%eax
>>     0xffffffffb9a4eb19:    jne    0xffffffffb9a4ecff
>> ---
>>
>> corresponding to this:
>> https://elixir.bootlin.com/linux/v5.10.4/source/crypto/asymmetric_keys/public_key.c#L359
>>
>> ---
>>     if (strcmp(sig->pkey_algo, "sm2") == 0 && sig->data_size) {
>>         ret = cert_sig_digest_update(sig, tfm);
>>         if (ret)
>>             goto error_free_key;
>>     }
>> ---
>>
>> So it seems like sig->pkey_algo is null. I will try to debug, but I
>> don't get access to an EAP-protected network often (maybe once or
>> twice a week), so it might take a while.
>>