wolfSSL / wolfssl

The wolfSSL library is a small, fast, portable implementation of TLS/SSL for embedded devices to the cloud. wolfSSL supports up to TLS 1.3 and DTLS 1.3!
https://www.wolfssl.com
GNU General Public License v2.0
2.24k stars 800 forks source link

[Bug]: client crash due to double-free when ECH acceptance check fails #6791

Closed sftcd closed 10 months ago

sftcd commented 10 months ago

Contact Details

via github is fine for now

Version

cloned master a few days ago

Description

I've got a version of curl that does ECH and can use ECH from my OpenSSL build or WolfSSL's. In the case of WolfSSL I can generate a crash due to a double-free by supplying a corrupted (coupla bits flipped in the public value) ECHConfig to the client.

Reproduction steps

You could reproduce if you were to build my curl fork HOWTO and then run:

./src/curl -vvv --echconfig AEX+DQBBYQAgACD8f/nTUp0hjj6R/yjh3KnNKWK/eG4FFvkfZbTNI84NPwAEAAEAAQASY2xvdWRmbGFyZS1lY2guY29tAAA= https://crypto.cloudflare.com/cdn-cgi/trace

There's a valgrind output below that shows where the problem lies.

The solution (that works for me) is to avoid the double-free when ECH acceptance checking fails as well as when it works. The commit is pretty simple and fairly obvious when you look at it.

Relevant log output

==1721996== Invalid write of size 8
==1721996==    at 0x4BC7766: ForceZero (misc.c:394)
==1721996==    by 0x4BC8CE2: wc_Sha256Free (sha256.c:1822)
==1721996==    by 0x4C2A59F: FreeHandshakeHashes (internal.c:6855)
==1721996==    by 0x4C2B8B0: SSL_ResourceFree (internal.c:7955)
==1721996==    by 0x4C2C007: FreeSSL (internal.c:8480)
==1721996==    by 0x4C6E031: wolfSSL_free (ssl.c:1493)
==1721996==    by 0x4903276: wolfssl_close (wolfssl.c:1126)
==1721996==    by 0x48FF5BC: cf_close (vtls.c:1424)
==1721996==    by 0x48FF962: ssl_cf_close (vtls.c:1496)
==1721996==    by 0x4875FC5: cf_setup_close (connect.c:1304)
==1721996==    by 0x487101D: Curl_conn_cf_close (cfilters.c:303)
==1721996==    by 0x486AE7F: cf_hc_baller_reset (cf-https-connect.c:65)
==1721996==  Address 0x756a430 is 576 bytes inside a block of size 1,152 free'd
==1721996==    at 0x484620F: free (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==1721996==    by 0x4BEFE53: wolfSSL_Free (memory.c:429)
==1721996==    by 0x4C2A5EA: FreeHandshakeHashes (internal.c:6876)
==1721996==    by 0x4CB99B9: EchCheckAcceptance (tls13.c:4808)
==1721996==    by 0x4CBA5BB: DoTls13ServerHello (tls13.c:5400)
==1721996==    by 0x4CBFA97: DoTls13HandShakeMsgType (tls13.c:11405)
==1721996==    by 0x4CC014D: DoTls13HandShakeMsg (tls13.c:11774)
==1721996==    by 0x4C36C85: ProcessReplyEx (internal.c:20830)
==1721996==    by 0x4C35F48: ProcessReply (internal.c:20070)
==1721996==    by 0x4C7833F: wolfSSL_connect (ssl.c:12445)
==1721996==    by 0x49027FF: wolfssl_connect_step2 (wolfssl.c:837)
==1721996==    by 0x490397D: wolfssl_connect_common (wolfssl.c:1350)
==1721996==  Block was alloc'd at
==1721996==    at 0x4843828: malloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==1721996==    by 0x4BEFE0F: wolfSSL_Malloc (memory.c:344)
==1721996==    by 0x4C2A3B8: InitHandshakeHashes (internal.c:6781)
==1721996==    by 0x4C2A64D: InitHandshakeHashesAndCopy (internal.c:6895)
==1721996==    by 0x4CB8B76: EchHashHelloInner (tls13.c:4128)
==1721996==    by 0x4CB94C6: SendTls13ClientHello (tls13.c:4596)
==1721996==    by 0x4C3DF53: SendClientHello (internal.c:27518)
==1721996==    by 0x4C78281: wolfSSL_connect (ssl.c:12421)
==1721996==    by 0x49027FF: wolfssl_connect_step2 (wolfssl.c:837)
==1721996==    by 0x490397D: wolfssl_connect_common (wolfssl.c:1350)
==1721996==    by 0x4903A81: wolfssl_connect_nonblocking (wolfssl.c:1382)
==1721996==    by 0x48FD4C7: ssl_connect_nonblocking (vtls.c:375)
==1721996== 
==1721996== Invalid write of size 8
==1721996==    at 0x4BE619D: ForceZero (misc.c:394)
==1721996==    by 0x4BE91E4: wc_Sha384Free (sha512.c:1487)
==1721996==    by 0x4C2A5B5: FreeHandshakeHashes (internal.c:6858)
==1721996==    by 0x4C2B8B0: SSL_ResourceFree (internal.c:7955)
==1721996==    by 0x4C2C007: FreeSSL (internal.c:8480)
==1721996==    by 0x4C6E031: wolfSSL_free (ssl.c:1493)
==1721996==    by 0x4903276: wolfssl_close (wolfssl.c:1126)
==1721996==    by 0x48FF5BC: cf_close (vtls.c:1424)
==1721996==    by 0x48FF962: ssl_cf_close (vtls.c:1496)
==1721996==    by 0x4875FC5: cf_setup_close (connect.c:1304)
==1721996==    by 0x487101D: Curl_conn_cf_close (cfilters.c:303)
==1721996==    by 0x486AE7F: cf_hc_baller_reset (cf-https-connect.c:65)
==1721996==  Address 0x756a4b0 is 704 bytes inside a block of size 1,152 free'd
==1721996==    at 0x484620F: free (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==1721996==    by 0x4BEFE53: wolfSSL_Free (memory.c:429)
==1721996==    by 0x4C2A5EA: FreeHandshakeHashes (internal.c:6876)
==1721996==    by 0x4CB99B9: EchCheckAcceptance (tls13.c:4808)
==1721996==    by 0x4CBA5BB: DoTls13ServerHello (tls13.c:5400)
==1721996==    by 0x4CBFA97: DoTls13HandShakeMsgType (tls13.c:11405)
==1721996==    by 0x4CC014D: DoTls13HandShakeMsg (tls13.c:11774)
==1721996==    by 0x4C36C85: ProcessReplyEx (internal.c:20830)
==1721996==    by 0x4C35F48: ProcessReply (internal.c:20070)
==1721996==    by 0x4C7833F: wolfSSL_connect (ssl.c:12445)
==1721996==    by 0x49027FF: wolfssl_connect_step2 (wolfssl.c:837)
==1721996==    by 0x490397D: wolfssl_connect_common (wolfssl.c:1350)
==1721996==  Block was alloc'd at
==1721996==    at 0x4843828: malloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==1721996==    by 0x4BEFE0F: wolfSSL_Malloc (memory.c:344)
==1721996==    by 0x4C2A3B8: InitHandshakeHashes (internal.c:6781)
==1721996==    by 0x4C2A64D: InitHandshakeHashesAndCopy (internal.c:6895)
==1721996==    by 0x4CB8B76: EchHashHelloInner (tls13.c:4128)
==1721996==    by 0x4CB94C6: SendTls13ClientHello (tls13.c:4596)
==1721996==    by 0x4C3DF53: SendClientHello (internal.c:27518)
==1721996==    by 0x4C78281: wolfSSL_connect (ssl.c:12421)
==1721996==    by 0x49027FF: wolfssl_connect_step2 (wolfssl.c:837)
==1721996==    by 0x490397D: wolfssl_connect_common (wolfssl.c:1350)
==1721996==    by 0x4903A81: wolfssl_connect_nonblocking (wolfssl.c:1382)
==1721996==    by 0x48FD4C7: ssl_connect_nonblocking (vtls.c:375)
==1721996== 
==1721996== Invalid write of size 8
==1721996==    at 0x4BE619D: ForceZero (misc.c:394)
==1721996==    by 0x4BE8E23: wc_Sha512Free (sha512.c:1151)
==1721996==    by 0x4C2A5CB: FreeHandshakeHashes (internal.c:6861)
==1721996==    by 0x4C2B8B0: SSL_ResourceFree (internal.c:7955)
==1721996==    by 0x4C2C007: FreeSSL (internal.c:8480)
==1721996==    by 0x4C6E031: wolfSSL_free (ssl.c:1493)
==1721996==    by 0x4903276: wolfssl_close (wolfssl.c:1126)
==1721996==    by 0x48FF5BC: cf_close (vtls.c:1424)
==1721996==    by 0x48FF962: ssl_cf_close (vtls.c:1496)
==1721996==    by 0x4875FC5: cf_setup_close (connect.c:1304)
==1721996==    by 0x487101D: Curl_conn_cf_close (cfilters.c:303)
==1721996==    by 0x486AE7F: cf_hc_baller_reset (cf-https-connect.c:65)
==1721996==  Address 0x756a590 is 928 bytes inside a block of size 1,152 free'd
==1721996==    at 0x484620F: free (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==1721996==    by 0x4BEFE53: wolfSSL_Free (memory.c:429)
==1721996==    by 0x4C2A5EA: FreeHandshakeHashes (internal.c:6876)
==1721996==    by 0x4CB99B9: EchCheckAcceptance (tls13.c:4808)
==1721996==    by 0x4CBA5BB: DoTls13ServerHello (tls13.c:5400)
==1721996==    by 0x4CBFA97: DoTls13HandShakeMsgType (tls13.c:11405)
==1721996==    by 0x4CC014D: DoTls13HandShakeMsg (tls13.c:11774)
==1721996==    by 0x4C36C85: ProcessReplyEx (internal.c:20830)
==1721996==    by 0x4C35F48: ProcessReply (internal.c:20070)
==1721996==    by 0x4C7833F: wolfSSL_connect (ssl.c:12445)
==1721996==    by 0x49027FF: wolfssl_connect_step2 (wolfssl.c:837)
==1721996==    by 0x490397D: wolfssl_connect_common (wolfssl.c:1350)
==1721996==  Block was alloc'd at
==1721996==    at 0x4843828: malloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==1721996==    by 0x4BEFE0F: wolfSSL_Malloc (memory.c:344)
==1721996==    by 0x4C2A3B8: InitHandshakeHashes (internal.c:6781)
==1721996==    by 0x4C2A64D: InitHandshakeHashesAndCopy (internal.c:6895)
==1721996==    by 0x4CB8B76: EchHashHelloInner (tls13.c:4128)
==1721996==    by 0x4CB94C6: SendTls13ClientHello (tls13.c:4596)
==1721996==    by 0x4C3DF53: SendClientHello (internal.c:27518)
==1721996==    by 0x4C78281: wolfSSL_connect (ssl.c:12421)
==1721996==    by 0x49027FF: wolfssl_connect_step2 (wolfssl.c:837)
==1721996==    by 0x490397D: wolfssl_connect_common (wolfssl.c:1350)
==1721996==    by 0x4903A81: wolfssl_connect_nonblocking (wolfssl.c:1382)
==1721996==    by 0x48FD4C7: ssl_connect_nonblocking (vtls.c:375)
==1721996== 
==1721996== Invalid free() / delete / delete[] / realloc()
==1721996==    at 0x484620F: free (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==1721996==    by 0x4BEFE53: wolfSSL_Free (memory.c:429)
==1721996==    by 0x4C2A5EA: FreeHandshakeHashes (internal.c:6876)
==1721996==    by 0x4C2B8B0: SSL_ResourceFree (internal.c:7955)
==1721996==    by 0x4C2C007: FreeSSL (internal.c:8480)
==1721996==    by 0x4C6E031: wolfSSL_free (ssl.c:1493)
==1721996==    by 0x4903276: wolfssl_close (wolfssl.c:1126)
==1721996==    by 0x48FF5BC: cf_close (vtls.c:1424)
==1721996==    by 0x48FF962: ssl_cf_close (vtls.c:1496)
==1721996==    by 0x4875FC5: cf_setup_close (connect.c:1304)
==1721996==    by 0x487101D: Curl_conn_cf_close (cfilters.c:303)
==1721996==    by 0x486AE7F: cf_hc_baller_reset (cf-https-connect.c:65)
==1721996==  Address 0x756a1f0 is 0 bytes inside a block of size 1,152 free'd
==1721996==    at 0x484620F: free (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==1721996==    by 0x4BEFE53: wolfSSL_Free (memory.c:429)
==1721996==    by 0x4C2A5EA: FreeHandshakeHashes (internal.c:6876)
==1721996==    by 0x4CB99B9: EchCheckAcceptance (tls13.c:4808)
==1721996==    by 0x4CBA5BB: DoTls13ServerHello (tls13.c:5400)
==1721996==    by 0x4CBFA97: DoTls13HandShakeMsgType (tls13.c:11405)
==1721996==    by 0x4CC014D: DoTls13HandShakeMsg (tls13.c:11774)
==1721996==    by 0x4C36C85: ProcessReplyEx (internal.c:20830)
==1721996==    by 0x4C35F48: ProcessReply (internal.c:20070)
==1721996==    by 0x4C7833F: wolfSSL_connect (ssl.c:12445)
==1721996==    by 0x49027FF: wolfssl_connect_step2 (wolfssl.c:837)
==1721996==    by 0x490397D: wolfssl_connect_common (wolfssl.c:1350)
==1721996==  Block was alloc'd at
==1721996==    at 0x4843828: malloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==1721996==    by 0x4BEFE0F: wolfSSL_Malloc (memory.c:344)
==1721996==    by 0x4C2A3B8: InitHandshakeHashes (internal.c:6781)
==1721996==    by 0x4C2A64D: InitHandshakeHashesAndCopy (internal.c:6895)
==1721996==    by 0x4CB8B76: EchHashHelloInner (tls13.c:4128)
==1721996==    by 0x4CB94C6: SendTls13ClientHello (tls13.c:4596)
==1721996==    by 0x4C3DF53: SendClientHello (internal.c:27518)
==1721996==    by 0x4C78281: wolfSSL_connect (ssl.c:12421)
==1721996==    by 0x49027FF: wolfssl_connect_step2 (wolfssl.c:837)
==1721996==    by 0x490397D: wolfssl_connect_common (wolfssl.c:1350)
==1721996==    by 0x4903A81: wolfssl_connect_nonblocking (wolfssl.c:1382)
==1721996==    by 0x48FD4C7: ssl_connect_nonblocking (vtls.c:375)
jpbland1 commented 10 months ago

Hey @sftcd,

Thanks for the heads up, I should have been calling free and setting that to NULL regardless of acceptance. I've made PR https://github.com/wolfSSL/wolfssl/pull/6795 to fix this issue. I tested the fix with your experimental version of curl, awesome stuff.

Best Wishes, John Bland

sftcd commented 10 months ago

Your fix looks good to me, thanks.