Keyrings Archive on lore.kernel.org
 help / color / Atom feed
* Null pointer dereference in public key verification (related to SM2 introduction)
@ 2020-11-12 10:19 Tobias Markus
  2020-11-30  9:09 ` David Howells
  0 siblings, 1 reply; 6+ messages in thread
From: Tobias Markus @ 2020-11-12 10:19 UTC (permalink / raw)
  To: linux-crypto
  Cc: Herbert Xu, Tianjia Zhang, David Howells, David S. Miller, keyrings

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

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: Null pointer dereference in public key verification (related to SM2 introduction)
  2020-11-12 10:19 Null pointer dereference in public key verification (related to SM2 introduction) Tobias Markus
@ 2020-11-30  9:09 ` David Howells
  2020-12-02 12:24   ` Tobias Markus
  0 siblings, 1 reply; 6+ messages in thread
From: David Howells @ 2020-11-30  9:09 UTC (permalink / raw)
  To: Tobias Markus
  Cc: dhowells, linux-crypto, Herbert Xu, Tianjia Zhang,
	David S. Miller, keyrings

Tobias Markus <tobias@markus-regensburg.de> 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


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: Null pointer dereference in public key verification (related to SM2 introduction)
  2020-11-30  9:09 ` David Howells
@ 2020-12-02 12:24   ` Tobias Markus
  2021-01-07  7:27     ` Tee Hao Wei
  0 siblings, 1 reply; 6+ messages in thread
From: Tobias Markus @ 2020-12-02 12:24 UTC (permalink / raw)
  To: David Howells
  Cc: linux-crypto, Herbert Xu, Tianjia Zhang, David S. Miller, keyrings


[-- Attachment #1: Type: text/plain, Size: 3526 bytes --]

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 <tobias@markus-regensburg.de> 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
> 

[-- Attachment #2: disassembly.txt --]
[-- Type: text/plain, Size: 27214 bytes --]

Dump of assembler code for function public_key_verify_signature:
crypto/asymmetric_keys/public_key.c:
311	{
   0xffffffff8158cd70 <+0>:	call   0xffffffff810cb580 <__fentry__>
   0xffffffff8158cd75 <+5>:	push   %r15
   0xffffffff8158cd77 <+7>:	mov    $0x8,%ecx
   0xffffffff8158cd7c <+12>:	push   %r14
   0xffffffff8158cd7e <+14>:	push   %r13
   0xffffffff8158cd80 <+16>:	push   %r12
   0xffffffff8158cd82 <+18>:	push   %rbp
   0xffffffff8158cd83 <+19>:	push   %rbx
   0xffffffff8158cd84 <+20>:	mov    %rdi,%rbx
   0xffffffff8158cd87 <+23>:	sub    $0x100,%rsp
   0xffffffff8158cd8e <+30>:	mov    %gs:0x28,%rax
   0xffffffff8158cd97 <+39>:	mov    %rax,0xf8(%rsp)
   0xffffffff8158cd9f <+47>:	xor    %eax,%eax
   0xffffffff8158cda1 <+49>:	lea    0x38(%rsp),%r13

312		struct crypto_wait cwait;
313		struct crypto_akcipher *tfm;
314		struct akcipher_request *req;
315		struct scatterlist src_sg[2];
316		char alg_name[CRYPTO_MAX_ALG_NAME];
317		char *key, *ptr;
318		int ret;
319	
320		pr_devel("==>%s()\n", __func__);
321	
322		BUG_ON(!pkey);
   0xffffffff8158cda6 <+54>:	test   %rbx,%rbx
   0xffffffff8158cda9 <+57>:	movq   $0x0,0x10(%rsp)
   0xffffffff8158cdb2 <+66>:	lea    0x78(%rsp),%r12
   0xffffffff8158cdb7 <+71>:	mov    %r13,%rdi
   0xffffffff8158cdba <+74>:	movq   $0x0,0x18(%rsp)
   0xffffffff8158cdc3 <+83>:	movq   $0x0,0x20(%rsp)
   0xffffffff8158cdcc <+92>:	movq   $0x0,0x28(%rsp)
   0xffffffff8158cdd5 <+101>:	movq   $0x0,0x30(%rsp)
   0xffffffff8158cdde <+110>:	rep stos %rax,%es:(%rdi)
   0xffffffff8158cde1 <+113>:	mov    $0x10,%ecx
   0xffffffff8158cde6 <+118>:	mov    %r12,%rdi
   0xffffffff8158cde9 <+121>:	rep stos %rax,%es:(%rdi)
   0xffffffff8158cdec <+124>:	je     0xffffffff8158d0be <public_key_verify_signature+846>

323		BUG_ON(!sig);
   0xffffffff8158cdf2 <+130>:	test   %rsi,%rsi
   0xffffffff8158cdf5 <+133>:	mov    %rsi,%rbp
   0xffffffff8158cdf8 <+136>:	je     0xffffffff8158d0c0 <public_key_verify_signature+848>

324		BUG_ON(!sig->s);
   0xffffffff8158cdfe <+142>:	cmpq   $0x0,0x10(%rsi)
   0xffffffff8158ce03 <+147>:	je     0xffffffff8158d0c2 <public_key_verify_signature+850>

325	
326		ret = software_key_determine_akcipher(sig->encoding,
   0xffffffff8158ce09 <+153>:	mov    0x38(%rsi),%rsi
   0xffffffff8158ce0d <+157>:	mov    %r12,%rcx
   0xffffffff8158ce10 <+160>:	mov    %rbx,%rdx
   0xffffffff8158ce13 <+163>:	mov    0x40(%rbp),%rdi
   0xffffffff8158ce17 <+167>:	call   0xffffffff8158ca80 <software_key_determine_akcipher>

327						      sig->hash_algo,
328						      pkey, alg_name);
329		if (ret < 0)
   0xffffffff8158ce1c <+172>:	test   %eax,%eax
   0xffffffff8158ce1e <+174>:	js     0xffffffff8158d07e <public_key_verify_signature+782>

330			return ret;
331	
332		tfm = crypto_alloc_akcipher(alg_name, 0, 0);
   0xffffffff8158ce24 <+180>:	xor    %edx,%edx
   0xffffffff8158ce26 <+182>:	xor    %esi,%esi
   0xffffffff8158ce28 <+184>:	mov    %r12,%rdi
   0xffffffff8158ce2b <+187>:	call   0xffffffff8156fa50 <crypto_alloc_akcipher>

333		if (IS_ERR(tfm))
   0xffffffff8158ce30 <+192>:	cmp    $0xfffffffffffff000,%rax

332		tfm = crypto_alloc_akcipher(alg_name, 0, 0);
   0xffffffff8158ce36 <+198>:	mov    %rax,%r12

./include/linux/err.h:
36		return IS_ERR_VALUE((unsigned long)ptr);
   0xffffffff8158ce39 <+201>:	ja     0xffffffff8158d07e <public_key_verify_signature+782>

./include/linux/slab.h:
557		return __kmalloc(size, flags);
   0xffffffff8158ce3f <+207>:	mov    0x10(%rax),%rax
   0xffffffff8158ce43 <+211>:	mov    $0xcc0,%esi

./include/crypto/akcipher.h:
196		req = kmalloc(sizeof(*req) + crypto_akcipher_reqsize(tfm), gfp);
   0xffffffff8158ce48 <+216>:	mov    -0x8(%rax),%edi
   0xffffffff8158ce4b <+219>:	add    $0x48,%rdi

./include/linux/slab.h:
557		return __kmalloc(size, flags);
   0xffffffff8158ce4f <+223>:	call   0xffffffff8133e020 <__kmalloc>

./include/crypto/akcipher.h:
197		if (likely(req))
   0xffffffff8158ce54 <+228>:	test   %rax,%rax

./include/linux/slab.h:
557		return __kmalloc(size, flags);
   0xffffffff8158ce57 <+231>:	mov    %rax,%r14

./include/crypto/akcipher.h:
197		if (likely(req))
   0xffffffff8158ce5a <+234>:	je     0xffffffff8158d0c4 <public_key_verify_signature+852>

136		return &tfm->base;
   0xffffffff8158ce60 <+240>:	mov    0x8(%rbx),%edx

137	}
138	
139	static inline struct akcipher_alg *__crypto_akcipher_alg(struct crypto_alg *alg)
140	{
141		return container_of(alg, struct akcipher_alg, base);
142	}
143	
144	static inline struct crypto_akcipher *__crypto_akcipher_tfm(
145		struct crypto_tfm *tfm)
146	{
147		return container_of(tfm, struct crypto_akcipher, base);
148	}
149	
150	static inline struct akcipher_alg *crypto_akcipher_alg(
151		struct crypto_akcipher *tfm)
152	{
153		return __crypto_akcipher_alg(crypto_akcipher_tfm(tfm)->__crt_alg);
154	}
155	
156	static inline unsigned int crypto_akcipher_reqsize(struct crypto_akcipher *tfm)
157	{
158		return crypto_akcipher_alg(tfm)->reqsize;
159	}
160	
161	static inline void akcipher_request_set_tfm(struct akcipher_request *req,
162						    struct crypto_akcipher *tfm)
163	{
164		req->base.tfm = crypto_akcipher_tfm(tfm);
   0xffffffff8158ce63 <+243>:	mov    %r12,0x20(%rax)

./include/linux/slab.h:
557		return __kmalloc(size, flags);
   0xffffffff8158ce67 <+247>:	mov    $0xcc0,%esi

crypto/asymmetric_keys/public_key.c:
341		key = kmalloc(pkey->keylen + sizeof(u32) * 2 + pkey->paramlen,
   0xffffffff8158ce6c <+252>:	mov    0x18(%rbx),%eax
   0xffffffff8158ce6f <+255>:	lea    0x8(%rdx,%rax,1),%rdi

./include/linux/slab.h:
557		return __kmalloc(size, flags);
   0xffffffff8158ce74 <+260>:	call   0xffffffff8133e020 <__kmalloc>

crypto/asymmetric_keys/public_key.c:
343		if (!key)
   0xffffffff8158ce79 <+265>:	test   %rax,%rax

./include/linux/slab.h:
557		return __kmalloc(size, flags);
   0xffffffff8158ce7c <+268>:	mov    %rax,%r15

crypto/asymmetric_keys/public_key.c:
343		if (!key)
   0xffffffff8158ce7f <+271>:	je     0xffffffff8158d12a <public_key_verify_signature+954>

344			goto error_free_req;
345	
346		memcpy(key, pkey->key, pkey->keylen);
   0xffffffff8158ce85 <+277>:	mov    0x8(%rbx),%edx

./include/linux/string.h:
399		return __underlying_memcpy(p, q, size);
   0xffffffff8158ce88 <+280>:	mov    %rax,%rdi
   0xffffffff8158ce8b <+283>:	mov    (%rbx),%rsi

crypto/asymmetric_keys/public_key.c:
346		memcpy(key, pkey->key, pkey->keylen);
   0xffffffff8158ce8e <+286>:	mov    %edx,0xc(%rsp)

./include/linux/string.h:
399		return __underlying_memcpy(p, q, size);
   0xffffffff8158ce92 <+290>:	mov    %rdx,(%rsp)
   0xffffffff8158ce96 <+294>:	call   0xffffffff81fd7590 <memcpy>

crypto/asymmetric_keys/public_key.c:
347		ptr = key + pkey->keylen;
   0xffffffff8158ce9b <+299>:	mov    (%rsp),%rdx
   0xffffffff8158ce9f <+303>:	mov    0xc(%rbx),%eax

./include/linux/string.h:
399		return __underlying_memcpy(p, q, size);
   0xffffffff8158cea2 <+306>:	mov    0x10(%rbx),%rsi

crypto/asymmetric_keys/public_key.c:
347		ptr = key + pkey->keylen;
   0xffffffff8158cea6 <+310>:	lea    (%r15,%rdx,1),%rdi

./include/linux/string.h:
399		return __underlying_memcpy(p, q, size);
   0xffffffff8158ceaa <+314>:	mov    0x18(%rbx),%edx
   0xffffffff8158cead <+317>:	mov    %eax,(%rdi)
   0xffffffff8158ceaf <+319>:	add    $0x8,%rdi
   0xffffffff8158ceb3 <+323>:	mov    %edx,-0x4(%rdi)
   0xffffffff8158ceb6 <+326>:	call   0xffffffff81fd7590 <memcpy>

crypto/asymmetric_keys/public_key.c:
352		if (pkey->key_is_private)
   0xffffffff8158cebb <+331>:	cmpb   $0x0,0x1c(%rbx)
   0xffffffff8158cebf <+335>:	mov    0xc(%rsp),%r8d

./include/crypto/akcipher.h:
414		return alg->set_priv_key(tfm, key, keylen);
   0xffffffff8158cec4 <+340>:	mov    0x10(%r12),%rax

crypto/asymmetric_keys/public_key.c:
352		if (pkey->key_is_private)
   0xffffffff8158cec9 <+345>:	jne    0xffffffff8158d0a7 <public_key_verify_signature+823>

./include/crypto/akcipher.h:
392		return alg->set_pub_key(tfm, key, keylen);
   0xffffffff8158cecf <+351>:	mov    -0x30(%rax),%rax
   0xffffffff8158ced3 <+355>:	mov    %r8d,%edx
   0xffffffff8158ced6 <+358>:	mov    %r15,%rsi
   0xffffffff8158ced9 <+361>:	mov    %r12,%rdi
   0xffffffff8158cedc <+364>:	call   0xffffffff82204c40 <__x86_indirect_thunk_rax>

crypto/asymmetric_keys/public_key.c:
356		if (ret)
   0xffffffff8158cee1 <+369>:	test   %eax,%eax
   0xffffffff8158cee3 <+371>:	jne    0xffffffff8158d059 <public_key_verify_signature+745>

357			goto error_free_key;
358	    
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>

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>

361			ret = cert_sig_digest_update(sig, tfm);
362			if (ret)
363				goto error_free_key;
364		}
365	
366		sg_init_table(src_sg, 2);
   0xffffffff8158cf18 <+424>:	mov    %r13,%rdi
   0xffffffff8158cf1b <+427>:	mov    $0x2,%esi
   0xffffffff8158cf20 <+432>:	call   0xffffffff815e2980 <sg_init_table>

367		sg_set_buf(&src_sg[0], sig->s, sig->s_size);
   0xffffffff8158cf25 <+437>:	mov    0x10(%rbp),%rax
   0xffffffff8158cf29 <+441>:	mov    $0x80000000,%ecx
   0xffffffff8158cf2e <+446>:	mov    0x18(%rbp),%edx

./include/linux/scatterlist.h:
145		sg_set_page(sg, virt_to_page(buf), buflen, offset_in_page(buf));
   0xffffffff8158cf31 <+449>:	mov    %eax,%edi
   0xffffffff8158cf33 <+451>:	and    $0xfff,%edi

./arch/x86/include/asm/page_64.h:
20		unsigned long y = x - __START_KERNEL_map;
   0xffffffff8158cf39 <+457>:	add    %rcx,%rax
   0xffffffff8158cf3c <+460>:	jb     0xffffffff8158d147 <public_key_verify_signature+983>

21	
22		/* use the carry flag to determine if x was < __START_KERNEL_map */
23		x = y + ((x > y) ? phys_base : (__START_KERNEL_map - PAGE_OFFSET));
   0xffffffff8158cf42 <+466>:	mov    $0xffffffff80000000,%rsi
   0xffffffff8158cf49 <+473>:	sub    0x17c3b00(%rip),%rsi        # 0xffffffff82d50a50 <page_offset_base>

24	
25		return x;
   0xffffffff8158cf50 <+480>:	mov    0x17c3ae9(%rip),%rcx        # 0xffffffff82d50a40 <vmemmap_base>

23		x = y + ((x > y) ? phys_base : (__START_KERNEL_map - PAGE_OFFSET));
   0xffffffff8158cf57 <+487>:	add    %rsi,%rax

./include/linux/scatterlist.h:
145		sg_set_page(sg, virt_to_page(buf), buflen, offset_in_page(buf));
   0xffffffff8158cf5a <+490>:	shr    $0xc,%rax
   0xffffffff8158cf5e <+494>:	shl    $0x6,%rax
   0xffffffff8158cf62 <+498>:	lea    (%rax,%rcx,1),%rsi

89		unsigned long page_link = sg->page_link & (SG_CHAIN | SG_END);
   0xffffffff8158cf66 <+502>:	mov    0x38(%rsp),%rax
   0xffffffff8158cf6b <+507>:	and    $0x3,%eax

90	
91		/*
92		 * In order for the low bit stealing approach to work, pages
93		 * must be aligned at a 32-bit boundary as a minimum.
94		 */
95		BUG_ON((unsigned long) page & (SG_CHAIN | SG_END));
   0xffffffff8158cf6e <+510>:	test   $0x3,%cl
   0xffffffff8158cf71 <+513>:	jne    0xffffffff8158d121 <public_key_verify_signature+945>

96	#ifdef CONFIG_DEBUG_SG
97		BUG_ON(sg_is_chain(sg));
98	#endif
99		sg->page_link = page_link | (unsigned long) page;
   0xffffffff8158cf77 <+519>:	or     %rsi,%rax
   0xffffffff8158cf7a <+522>:	mov    $0x80000000,%esi

100	}
101	
102	/**
103	 * sg_set_page - Set sg entry to point at given page
104	 * @sg:		 SG entry
105	 * @page:	 The page
106	 * @len:	 Length of data
107	 * @offset:	 Offset into page
108	 *
109	 * Description:
110	 *   Use this function to set an sg entry pointing at a page, never assign
111	 *   the page directly. We encode sg table information in the lower bits
112	 *   of the page pointer. See sg_page() for looking up the page belonging
113	 *   to an sg entry.
114	 *
115	 **/
116	static inline void sg_set_page(struct scatterlist *sg, struct page *page,
117				       unsigned int len, unsigned int offset)
118	{
119		sg_assign_page(sg, page);
120		sg->offset = offset;
   0xffffffff8158cf7f <+527>:	mov    %edi,0x40(%rsp)

crypto/asymmetric_keys/public_key.c:
368		sg_set_buf(&src_sg[1], sig->digest, sig->digest_size);
   0xffffffff8158cf83 <+531>:	movzbl 0x28(%rbp),%edi

./include/linux/scatterlist.h:
99		sg->page_link = page_link | (unsigned long) page;
   0xffffffff8158cf87 <+535>:	mov    %rax,0x38(%rsp)

121		sg->length = len;
   0xffffffff8158cf8c <+540>:	mov    0x20(%rbp),%rax
   0xffffffff8158cf90 <+544>:	mov    %edx,0x44(%rsp)

122	}
123	
124	static inline struct page *sg_page(struct scatterlist *sg)
125	{
126	#ifdef CONFIG_DEBUG_SG
127		BUG_ON(sg_is_chain(sg));
128	#endif
129		return (struct page *)((sg)->page_link & ~(SG_CHAIN | SG_END));
130	}
131	
132	/**
133	 * sg_set_buf - Set sg entry to point at given data
134	 * @sg:		 SG entry
135	 * @buf:	 Data
136	 * @buflen:	 Data length
137	 *
138	 **/
139	static inline void sg_set_buf(struct scatterlist *sg, const void *buf,
140				      unsigned int buflen)
141	{
142	#ifdef CONFIG_DEBUG_SG
143		BUG_ON(!virt_addr_valid(buf));
144	#endif
145		sg_set_page(sg, virt_to_page(buf), buflen, offset_in_page(buf));
   0xffffffff8158cf94 <+548>:	mov    %eax,%r8d
   0xffffffff8158cf97 <+551>:	and    $0xfff,%r8d

./arch/x86/include/asm/page_64.h:
20		unsigned long y = x - __START_KERNEL_map;
   0xffffffff8158cf9e <+558>:	add    %rsi,%rax
   0xffffffff8158cfa1 <+561>:	jb     0xffffffff8158d153 <public_key_verify_signature+995>

21	
22		/* use the carry flag to determine if x was < __START_KERNEL_map */
23		x = y + ((x > y) ? phys_base : (__START_KERNEL_map - PAGE_OFFSET));
   0xffffffff8158cfa7 <+567>:	mov    $0xffffffff80000000,%rsi
   0xffffffff8158cfae <+574>:	sub    0x17c3a9b(%rip),%rsi        # 0xffffffff82d50a50 <page_offset_base>

24	
25		return x;
   0xffffffff8158cfb5 <+581>:	add    %rsi,%rax

./include/linux/scatterlist.h:
145		sg_set_page(sg, virt_to_page(buf), buflen, offset_in_page(buf));
   0xffffffff8158cfb8 <+584>:	shr    $0xc,%rax
   0xffffffff8158cfbc <+588>:	shl    $0x6,%rax
   0xffffffff8158cfc0 <+592>:	lea    (%rax,%rcx,1),%rsi

89		unsigned long page_link = sg->page_link & (SG_CHAIN | SG_END);
   0xffffffff8158cfc4 <+596>:	mov    0x58(%rsp),%rax
   0xffffffff8158cfc9 <+601>:	and    $0x3,%eax

90	
91		/*
92		 * In order for the low bit stealing approach to work, pages
93		 * must be aligned at a 32-bit boundary as a minimum.
94		 */
95		BUG_ON((unsigned long) page & (SG_CHAIN | SG_END));
   0xffffffff8158cfcc <+604>:	and    $0x3,%ecx
   0xffffffff8158cfcf <+607>:	jne    0xffffffff8158d123 <public_key_verify_signature+947>

96	#ifdef CONFIG_DEBUG_SG
97		BUG_ON(sg_is_chain(sg));
98	#endif
99		sg->page_link = page_link | (unsigned long) page;
   0xffffffff8158cfd5 <+613>:	or     %rsi,%rax

121		sg->length = len;
   0xffffffff8158cfd8 <+616>:	mov    %edi,0x64(%rsp)

./include/linux/completion.h:
88		init_swait_queue_head(&x->wait);
   0xffffffff8158cfdc <+620>:	mov    $0xffffffff82beaddd,%rsi

./include/crypto/akcipher.h:
254		req->src_len = src_len;
   0xffffffff8158cfe3 <+627>:	mov    %edx,0x40(%r14)

./include/linux/completion.h:
88		init_swait_queue_head(&x->wait);
   0xffffffff8158cfe7 <+631>:	mov    $0xffffffff83ab7a41,%rdx

./include/crypto/akcipher.h:
255		req->dst_len = dst_len;
   0xffffffff8158cfee <+638>:	mov    %edi,0x44(%r14)

./include/linux/completion.h:
88		init_swait_queue_head(&x->wait);
   0xffffffff8158cff2 <+642>:	lea    0x18(%rsp),%rdi

./include/linux/scatterlist.h:
99		sg->page_link = page_link | (unsigned long) page;
   0xffffffff8158cff7 <+647>:	mov    %rax,0x58(%rsp)

100	}
101	
102	/**
103	 * sg_set_page - Set sg entry to point at given page
104	 * @sg:		 SG entry
105	 * @page:	 The page
106	 * @len:	 Length of data
107	 * @offset:	 Offset into page
108	 *
109	 * Description:
110	 *   Use this function to set an sg entry pointing at a page, never assign
111	 *   the page directly. We encode sg table information in the lower bits
112	 *   of the page pointer. See sg_page() for looking up the page belonging
113	 *   to an sg entry.
114	 *
115	 **/
116	static inline void sg_set_page(struct scatterlist *sg, struct page *page,
117				       unsigned int len, unsigned int offset)
118	{
119		sg_assign_page(sg, page);
120		sg->offset = offset;
   0xffffffff8158cffc <+652>:	mov    %r8d,0x60(%rsp)

./include/crypto/akcipher.h:
252		req->src = src;
   0xffffffff8158d001 <+657>:	mov    %r13,0x30(%r14)

253		req->dst = dst;
   0xffffffff8158d005 <+661>:	movq   $0x0,0x38(%r14)

./include/linux/completion.h:
87		x->done = 0;
   0xffffffff8158d00d <+669>:	movl   $0x0,0x10(%rsp)

88		init_swait_queue_head(&x->wait);
   0xffffffff8158d015 <+677>:	call   0xffffffff811923d0 <__init_swait_queue_head>

./include/crypto/akcipher.h:
229		req->base.complete = cmpl;
   0xffffffff8158d01a <+682>:	movq   $0xffffffff81569180,0x10(%r14)

230		req->base.data = data;
   0xffffffff8158d022 <+690>:	mov    %r14,%rdi
   0xffffffff8158d025 <+693>:	lea    0x10(%rsp),%rax

231		req->base.flags = flgs;
   0xffffffff8158d02a <+698>:	movl   $0x600,0x28(%r14)

230		req->base.data = data;
   0xffffffff8158d032 <+706>:	mov    %rax,0x18(%r14)

256	}
257	
258	/**
259	 * crypto_akcipher_maxsize() - Get len for output buffer
260	 *
261	 * Function returns the dest buffer size required for a given key.
262	 * Function assumes that the key is already set in the transformation. If this
263	 * function is called without a setkey or with a failed setkey, you will end up
264	 * in a NULL dereference.
265	 *
266	 * @tfm:	AKCIPHER tfm handle allocated with crypto_alloc_akcipher()
267	 */
268	static inline unsigned int crypto_akcipher_maxsize(struct crypto_akcipher *tfm)
269	{
270		struct akcipher_alg *alg = crypto_akcipher_alg(tfm);
271	
272		return alg->max_size(tfm);
273	}
274	
275	/**
276	 * crypto_akcipher_encrypt() - Invoke public key encrypt operation
277	 *
278	 * Function invokes the specific public key encrypt operation for a given
279	 * public key algorithm
280	 *
281	 * @req:	asymmetric key request
282	 *
283	 * Return: zero on success; error code in case of error
284	 */
285	static inline int crypto_akcipher_encrypt(struct akcipher_request *req)
286	{
287		struct crypto_akcipher *tfm = crypto_akcipher_reqtfm(req);
288		struct akcipher_alg *alg = crypto_akcipher_alg(tfm);
289		struct crypto_alg *calg = tfm->base.__crt_alg;
290		unsigned int src_len = req->src_len;
291		int ret;
292	
293		crypto_stats_get(calg);
294		ret = alg->encrypt(req);
295		crypto_stats_akcipher_encrypt(src_len, ret, calg);
296		return ret;
297	}
298	
299	/**
300	 * crypto_akcipher_decrypt() - Invoke public key decrypt operation
301	 *
302	 * Function invokes the specific public key decrypt operation for a given
303	 * public key algorithm
304	 *
305	 * @req:	asymmetric key request
306	 *
307	 * Return: zero on success; error code in case of error
308	 */
309	static inline int crypto_akcipher_decrypt(struct akcipher_request *req)
310	{
311		struct crypto_akcipher *tfm = crypto_akcipher_reqtfm(req);
312		struct akcipher_alg *alg = crypto_akcipher_alg(tfm);
313		struct crypto_alg *calg = tfm->base.__crt_alg;
314		unsigned int src_len = req->src_len;
315		int ret;
316	
317		crypto_stats_get(calg);
318		ret = alg->decrypt(req);
319		crypto_stats_akcipher_decrypt(src_len, ret, calg);
320		return ret;
321	}
322	
323	/**
324	 * crypto_akcipher_sign() - Invoke public key sign operation
325	 *
326	 * Function invokes the specific public key sign operation for a given
327	 * public key algorithm
328	 *
329	 * @req:	asymmetric key request
330	 *
331	 * Return: zero on success; error code in case of error
332	 */
333	static inline int crypto_akcipher_sign(struct akcipher_request *req)
334	{
335		struct crypto_akcipher *tfm = crypto_akcipher_reqtfm(req);
336		struct akcipher_alg *alg = crypto_akcipher_alg(tfm);
337		struct crypto_alg *calg = tfm->base.__crt_alg;
338		int ret;
339	
340		crypto_stats_get(calg);
341		ret = alg->sign(req);
342		crypto_stats_akcipher_sign(ret, calg);
343		return ret;
344	}
345	
346	/**
347	 * crypto_akcipher_verify() - Invoke public key signature verification
348	 *
349	 * Function invokes the specific public key signature verification operation
350	 * for a given public key algorithm.
351	 *
352	 * @req:	asymmetric key request
353	 *
354	 * Note: req->dst should be NULL, req->src should point to SG of size
355	 * (req->src_size + req->dst_size), containing signature (of req->src_size
356	 * length) with appended digest (of req->dst_size length).
357	 *
358	 * Return: zero on verification success; error code in case of error.
359	 */
360	static inline int crypto_akcipher_verify(struct akcipher_request *req)
361	{
362		struct crypto_akcipher *tfm = crypto_akcipher_reqtfm(req);
363		struct akcipher_alg *alg = crypto_akcipher_alg(tfm);
364		struct crypto_alg *calg = tfm->base.__crt_alg;
365		int ret;
366	
367		crypto_stats_get(calg);
368		ret = alg->verify(req);
   0xffffffff8158d036 <+710>:	mov    0x20(%r14),%rax
   0xffffffff8158d03a <+714>:	mov    0x10(%rax),%rax
   0xffffffff8158d03e <+718>:	mov    -0x48(%rax),%rax
   0xffffffff8158d042 <+722>:	call   0xffffffff82204c40 <__x86_indirect_thunk_rax>

./include/linux/crypto.h:
590		switch (err) {
   0xffffffff8158d047 <+727>:	cmp    $0xffffff8d,%eax
   0xffffffff8158d04a <+730>:	je     0xffffffff8158d104 <public_key_verify_signature+916>
   0xffffffff8158d050 <+736>:	cmp    $0xfffffff0,%eax
   0xffffffff8158d053 <+739>:	je     0xffffffff8158d104 <public_key_verify_signature+916>

crypto/asymmetric_keys/public_key.c:
378		kfree(key);
   0xffffffff8158d059 <+745>:	mov    %r15,%rdi
   0xffffffff8158d05c <+748>:	mov    %eax,(%rsp)
   0xffffffff8158d05f <+751>:	call   0xffffffff8133c9c0 <kfree>

./include/crypto/akcipher.h:
210		kfree_sensitive(req);
   0xffffffff8158d064 <+756>:	mov    %r14,%rdi
   0xffffffff8158d067 <+759>:	call   0xffffffff812f0380 <kfree_sensitive>

136		return &tfm->base;
   0xffffffff8158d06c <+764>:	mov    %r12,%rsi
   0xffffffff8158d06f <+767>:	mov    %r12,%rdi
   0xffffffff8158d072 <+770>:	call   0xffffffff81569610 <crypto_destroy_tfm>

crypto/asymmetric_keys/public_key.c:
384		if (WARN_ON_ONCE(ret > 0))
   0xffffffff8158d077 <+775>:	mov    (%rsp),%eax
   0xffffffff8158d07a <+778>:	test   %eax,%eax
   0xffffffff8158d07c <+780>:	jg     0xffffffff8158d0d6 <public_key_verify_signature+870>

386		return ret;
387	}
   0xffffffff8158d07e <+782>:	mov    0xf8(%rsp),%rbx
   0xffffffff8158d086 <+790>:	sub    %gs:0x28,%rbx
   0xffffffff8158d08f <+799>:	jne    0xffffffff8158d125 <public_key_verify_signature+949>
   0xffffffff8158d095 <+805>:	add    $0x100,%rsp
   0xffffffff8158d09c <+812>:	pop    %rbx
   0xffffffff8158d09d <+813>:	pop    %rbp
   0xffffffff8158d09e <+814>:	pop    %r12
   0xffffffff8158d0a0 <+816>:	pop    %r13
   0xffffffff8158d0a2 <+818>:	pop    %r14
   0xffffffff8158d0a4 <+820>:	pop    %r15
   0xffffffff8158d0a6 <+822>:	ret    

./include/crypto/akcipher.h:
414		return alg->set_priv_key(tfm, key, keylen);
   0xffffffff8158d0a7 <+823>:	mov    %r8d,%edx
   0xffffffff8158d0aa <+826>:	mov    %r15,%rsi
   0xffffffff8158d0ad <+829>:	mov    %r12,%rdi
   0xffffffff8158d0b0 <+832>:	mov    -0x28(%rax),%rax
   0xffffffff8158d0b4 <+836>:	call   0xffffffff82204c40 <__x86_indirect_thunk_rax>
   0xffffffff8158d0b9 <+841>:	jmp    0xffffffff8158cee1 <public_key_verify_signature+369>

crypto/asymmetric_keys/public_key.c:
322		BUG_ON(!pkey);
   0xffffffff8158d0be <+846>:	ud2    

323		BUG_ON(!sig);
   0xffffffff8158d0c0 <+848>:	ud2    

324		BUG_ON(!sig->s);
   0xffffffff8158d0c2 <+850>:	ud2    

./include/crypto/akcipher.h:
136		return &tfm->base;
   0xffffffff8158d0c4 <+852>:	mov    %r12,%rsi
   0xffffffff8158d0c7 <+855>:	mov    %r12,%rdi
   0xffffffff8158d0ca <+858>:	call   0xffffffff81569610 <crypto_destroy_tfm>

crypto/asymmetric_keys/public_key.c:
384		if (WARN_ON_ONCE(ret > 0))
   0xffffffff8158d0cf <+863>:	mov    $0xfffffff4,%eax
   0xffffffff8158d0d4 <+868>:	jmp    0xffffffff8158d07e <public_key_verify_signature+782>
   0xffffffff8158d0d6 <+870>:	ud2    

385			ret = -EINVAL;
   0xffffffff8158d0d8 <+872>:	mov    $0xffffffea,%eax
   0xffffffff8158d0dd <+877>:	jmp    0xffffffff8158d07e <public_key_verify_signature+782>

378		kfree(key);
   0xffffffff8158d0df <+879>:	mov    %r15,%rdi
   0xffffffff8158d0e2 <+882>:	call   0xffffffff8133c9c0 <kfree>

./include/crypto/akcipher.h:
210		kfree_sensitive(req);
   0xffffffff8158d0e7 <+887>:	mov    %r14,%rdi
   0xffffffff8158d0ea <+890>:	call   0xffffffff812f0380 <kfree_sensitive>

136		return &tfm->base;
   0xffffffff8158d0ef <+895>:	mov    %r12,%rsi
   0xffffffff8158d0f2 <+898>:	mov    %r12,%rdi
   0xffffffff8158d0f5 <+901>:	call   0xffffffff81569610 <crypto_destroy_tfm>

crypto/asymmetric_keys/public_key.c:
384		if (WARN_ON_ONCE(ret > 0))
   0xffffffff8158d0fa <+906>:	mov    $0xfffffdf4,%eax
   0xffffffff8158d0ff <+911>:	jmp    0xffffffff8158d07e <public_key_verify_signature+782>

./include/linux/crypto.h:
593			wait_for_completion(&wait->completion);
   0xffffffff8158d104 <+916>:	lea    0x10(%rsp),%rdi
   0xffffffff8158d109 <+921>:	call   0xffffffff81fdb650 <wait_for_completion>

./include/linux/completion.h:
100		x->done = 0;
   0xffffffff8158d10e <+926>:	mov    0x30(%rsp),%eax
   0xffffffff8158d112 <+930>:	movl   $0x0,0x10(%rsp)

./include/linux/crypto.h:
599		return err;
   0xffffffff8158d11a <+938>:	jmp    0xffffffff8158d059 <public_key_verify_signature+745>

crypto/asymmetric_keys/public_key.c:
359	    BUG_ON(!sig->pkey_algo);
   0xffffffff8158d11f <+943>:	ud2    

./include/linux/scatterlist.h:
95		BUG_ON((unsigned long) page & (SG_CHAIN | SG_END));
   0xffffffff8158d121 <+945>:	ud2    
   0xffffffff8158d123 <+947>:	ud2    
   0xffffffff8158d125 <+949>:	call   0xffffffff81fd6eb0 <__stack_chk_fail>

./include/crypto/akcipher.h:
210		kfree_sensitive(req);
   0xffffffff8158d12a <+954>:	mov    %r14,%rdi
   0xffffffff8158d12d <+957>:	call   0xffffffff812f0380 <kfree_sensitive>

136		return &tfm->base;
   0xffffffff8158d132 <+962>:	mov    %r12,%rsi
   0xffffffff8158d135 <+965>:	mov    %r12,%rdi
   0xffffffff8158d138 <+968>:	call   0xffffffff81569610 <crypto_destroy_tfm>

crypto/asymmetric_keys/public_key.c:
384		if (WARN_ON_ONCE(ret > 0))
   0xffffffff8158d13d <+973>:	mov    $0xfffffff4,%eax
   0xffffffff8158d142 <+978>:	jmp    0xffffffff8158d07e <public_key_verify_signature+782>

./arch/x86/include/asm/page_64.h:
23		x = y + ((x > y) ? phys_base : (__START_KERNEL_map - PAGE_OFFSET));
   0xffffffff8158d147 <+983>:	mov    0x1a8bec2(%rip),%rsi        # 0xffffffff83019010 <phys_base>
   0xffffffff8158d14e <+990>:	jmp    0xffffffff8158cf50 <public_key_verify_signature+480>
   0xffffffff8158d153 <+995>:	mov    0x1a8beb6(%rip),%rsi        # 0xffffffff83019010 <phys_base>
   0xffffffff8158d15a <+1002>:	jmp    0xffffffff8158cfb5 <public_key_verify_signature+581>
End of assembler dump.

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: Null pointer dereference in public key verification (related to SM2 introduction)
  2020-12-02 12:24   ` Tobias Markus
@ 2021-01-07  7:27     ` Tee Hao Wei
  2021-01-07  7:58       ` Tianjia Zhang
  0 siblings, 1 reply; 6+ messages in thread
From: Tee Hao Wei @ 2021-01-07  7:27 UTC (permalink / raw)
  To: linux-crypto
  Cc: Herbert Xu, Tianjia Zhang, David S. Miller, keyrings,
	Tobias Markus, David Howells

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 <tobias@markus-regensburg.de> 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

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: Null pointer dereference in public key verification (related to SM2 introduction)
  2021-01-07  7:27     ` Tee Hao Wei
@ 2021-01-07  7:58       ` Tianjia Zhang
  2021-01-07  8:40         ` Jean-Louis Dupond
  0 siblings, 1 reply; 6+ messages in thread
From: Tianjia Zhang @ 2021-01-07  7:58 UTC (permalink / raw)
  To: Tee Hao Wei, linux-crypto
  Cc: Herbert Xu, David S. Miller, keyrings, Tobias Markus, David Howells

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 <tobias@markus-regensburg.de> 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.
> 

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: Null pointer dereference in public key verification (related to SM2 introduction)
  2021-01-07  7:58       ` Tianjia Zhang
@ 2021-01-07  8:40         ` Jean-Louis Dupond
  0 siblings, 0 replies; 6+ messages in thread
From: Jean-Louis Dupond @ 2021-01-07  8:40 UTC (permalink / raw)
  To: Tianjia Zhang, Tee Hao Wei, linux-crypto
  Cc: Herbert Xu, David S. Miller, keyrings, Tobias Markus, David Howells

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 <tobias@markus-regensburg.de> 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.
>>

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, back to index

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-11-12 10:19 Null pointer dereference in public key verification (related to SM2 introduction) Tobias Markus
2020-11-30  9:09 ` David Howells
2020-12-02 12:24   ` Tobias Markus
2021-01-07  7:27     ` Tee Hao Wei
2021-01-07  7:58       ` Tianjia Zhang
2021-01-07  8:40         ` Jean-Louis Dupond

Keyrings Archive on lore.kernel.org

Archives are clonable:
	git clone --mirror https://lore.kernel.org/keyrings/0 keyrings/git/0.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 keyrings keyrings/ https://lore.kernel.org/keyrings \
		keyrings@vger.kernel.org
	public-inbox-index keyrings

Example config snippet for mirrors

Newsgroup available over NNTP:
	nntp://nntp.lore.kernel.org/org.kernel.vger.keyrings


AGPL code for this site: git clone https://public-inbox.org/public-inbox.git