keyrings.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Tobias Markus <tobias@markus-regensburg.de>
To: David Howells <dhowells@redhat.com>
Cc: linux-crypto@vger.kernel.org,
	Herbert Xu <herbert@gondor.apana.org.au>,
	Tianjia Zhang <tianjia.zhang@linux.alibaba.com>,
	"David S. Miller" <davem@davemloft.net>,
	keyrings@vger.kernel.org
Subject: Re: Null pointer dereference in public key verification (related to SM2 introduction)
Date: Wed, 2 Dec 2020 13:24:27 +0100	[thread overview]
Message-ID: <96474593-2882-60a1-0dcf-5b3dc7526bfa@markus-regensburg.de> (raw)
In-Reply-To: <3092220.1606727387@warthog.procyon.org.uk>

[-- 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.

  reply	other threads:[~2020-12-02 12:38 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
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 [this message]
2021-01-07  7:27     ` Tee Hao Wei
2021-01-07  7:58       ` Tianjia Zhang
2021-01-07  8:40         ` Jean-Louis Dupond

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=96474593-2882-60a1-0dcf-5b3dc7526bfa@markus-regensburg.de \
    --to=tobias@markus-regensburg.de \
    --cc=davem@davemloft.net \
    --cc=dhowells@redhat.com \
    --cc=herbert@gondor.apana.org.au \
    --cc=keyrings@vger.kernel.org \
    --cc=linux-crypto@vger.kernel.org \
    --cc=tianjia.zhang@linux.alibaba.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).