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.
next prev parent 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).