c++ - 为什么 OpenSSL 会崩溃?

标签 c++ c openssl

这是我从 gdb 得到的回溯:

(gdb) bt
#0  0x040010c2 in ?? () from /lib/ld-linux.so.2
#1  0x06822a0b in write () at ../sysdeps/unix/syscall-template.S:82
#2  0x082e6891 in conn_write (b=0x9791b40, in=0xe9125a3 "\027\003\003", inl=175) at bss_conn.c:442
#3  0x082e40cb in BIO_write (b=0x9791b40, in=0xe9125a3, inl=175) at bio_lib.c:247
#4  0x08290991 in ssl3_write_pending (s=0xea22bd8, type=23, 
        buf=0xafdeb08 "Host: graph.facebook.com\r\nUser-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.4 (KHTML, like Gecko) Chrome/22.0.1229.94 Safari/537.4\r\n", len=146) at s3_pkt.c:881
#5  0x082908a4 in do_ssl3_write (s=0xea22bd8, type=23, 
        buf=0xafdeb08 "Host: graph.facebook.com\r\nUser-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.4 (KHTML, like Gecko) Chrome/22.0.1229.94 Safari/537.4\r\n", len=146, create_empty_fragment=0) at s3_pkt.c:853
#6  0x08290281 in ssl3_write_bytes (s=0xea22bd8, type=23, buf_=0xafdeb08, len=146) at s3_pkt.c:609
#7  0x0828d0c3 in ssl3_write (s=0xea22bd8, buf=0xafdeb08, len=146) at s3_lib.c:4204
#8  0x082a4eae in SSL_write (s=0xea22bd8, buf=0xafdeb08, num=146) at ssl_lib.c:1002
#9  0x082b363b in ssl_write (b=0xaf5ba48, 
        out=0xafdeb08 "Host: graph.facebook.com\r\nUser-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.4 (KHTML, like Gecko) Chrome/22.0.1229.94 Safari/537.4\r\n", outl=146) at bio_ssl.c:243
#10 0x082e40cb in BIO_write (b=0xaf5ba48, in=0xafdeb08, inl=146) at bio_lib.c:247
#11 0x0816c7db in SSL_Connection_send (connection=0xaf6ef10, 
        data=0xafdeb08 "Host: graph.facebook.com\r\nUser-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.4 (KHTML, like Gecko) Chrome/22.0.1229.94 Safari/537.4\r\n", length=146) at Util/SSL_Connection.cpp:318

这是第一个可疑的 valgrind 错误:

==2803== Syscall param write(buf) points to uninitialised byte(s)
==2803==    at 0x6822A0B: ??? (syscall-template.S:82)
==2803==    by 0x82E40CA: BIO_write (bio_lib.c:247)
==2803==    by 0x829790E: ssl23_write_bytes (s23_pkt.c:77)
==2803==    by 0x8296D63: ssl23_client_hello (s23_clnt.c:594)
==2803==    by 0x829621C: ssl23_connect (s23_clnt.c:217)
==2803==    by 0x82A785C: SSL_do_handshake (ssl_lib.c:2564)
==2803==    by 0x82B3C22: ssl_ctrl (bio_ssl.c:423)
==2803==    by 0x82E4552: BIO_ctrl (bio_lib.c:370)
==2803==    by 0x816C2AA: SSL_Connection_connect(SSL_Connection_s*) (SSL_Connection.cpp:162)
==2803==    by 0x8147C17: Connection_connectToHost (Connection.cpp:48)
==2803==    by 0x815E8B7: Http_client_send_prepare(Http_Message_s*) (Http_client.cpp:330)
==2803==    by 0x815E9FD: Http_client_send (Http_client.cpp:357)
==2803==  Address 0xe9e6f33 is 11 bytes inside a block of size 21,848 alloc'd
==2803==    at 0x4028876: malloc (vg_replace_malloc.c:236)
==2803==    by 0x82C898B: default_malloc_ex (mem.c:79)
==2803==    by 0x82C8EAA: CRYPTO_malloc (mem.c:308)
==2803==    by 0x82E349B: BUF_MEM_grow (buffer.c:121)
==2803==    by 0x8296198: ssl23_connect (s23_clnt.c:195)
==2803==    by 0x82A785C: SSL_do_handshake (ssl_lib.c:2564)
==2803==    by 0x82B3C22: ssl_ctrl (bio_ssl.c:423)
==2803==    by 0x82E4552: BIO_ctrl (bio_lib.c:370)
==2803==    by 0x816C2AA: SSL_Connection_connect(SSL_Connection_s*) (SSL_Connection.cpp:162)
==2803==    by 0x8147C17: Connection_connectToHost (Connection.cpp:48)
==2803==    by 0x815E8B7: Http_client_send_prepare(Http_Message_s*) (Http_client.cpp:330)
==2803==    by 0x815E9FD: Http_client_send (Http_client.cpp:357)

这是崩溃前最近的 valgrind 错误:

== Syscall param write(buf) points to uninitialised byte(s)
==2803==    at 0x6822A0B: ??? (syscall-template.S:82)
==2803==    by 0x82E40CA: BIO_write (bio_lib.c:247)
==2803==    by 0x8290990: ssl3_write_pending (s3_pkt.c:881)
==2803==    by 0x82908A3: do_ssl3_write (s3_pkt.c:853)
==2803==    by 0x8290280: ssl3_write_bytes (s3_pkt.c:609)
==2803==    by 0x828D0C2: ssl3_write (s3_lib.c:4204)
==2803==    by 0x82A4EAD: SSL_write (ssl_lib.c:1002)
==2803==    by 0x82B363A: ssl_write (bio_ssl.c:243)
==2803==    by 0x82E40CA: BIO_write (bio_lib.c:247)
==2803==    by 0x816C7DA: SSL_Connection_send(SSL_Connection_s*, char*, unsigned int) (SSL_Connection.cpp:318)
==2803==    by 0x8147F66: Connection_send (Connection.cpp:167)
==2803==    by 0x815EA67: Http_client_send (Http_client.cpp:368)
==2803==  Address 0xe9125a8 is 8 bytes inside a block of size 17,584 alloc'd
==2803==    at 0x4028876: malloc (vg_replace_malloc.c:236)
==2803==    by 0x82C898B: default_malloc_ex (mem.c:79)
==2803==    by 0x82C8EAA: CRYPTO_malloc (mem.c:308)
==2803==    by 0x8293115: freelist_extract (s3_both.c:708)
==2803==    by 0x8293412: ssl3_setup_write_buffer (s3_both.c:811)
==2803==    by 0x829349B: ssl3_setup_buffers (s3_both.c:829)
==2803==    by 0x82961C3: ssl23_connect (s23_clnt.c:204)
==2803==    by 0x82A785C: SSL_do_handshake (ssl_lib.c:2564)
==2803==    by 0x82B3C22: ssl_ctrl (bio_ssl.c:423)
==2803==    by 0x82E4552: BIO_ctrl (bio_lib.c:370)
==2803==    by 0x816C2AA: SSL_Connection_connect(SSL_Connection_s*) (SSL_Connection.cpp:162)
==2803==    by 0x8147C17: Connection_connectToHost (Connection.cpp:48)

使用 --track-origins:

==3588== Syscall param write(buf) points to uninitialised byte(s)
==3588==    at 0x6822A0B: ??? (syscall-template.S:82)
==3588==    by 0x82E40CA: BIO_write (bio_lib.c:247)
==3588==    by 0x829790E: ssl23_write_bytes (s23_pkt.c:77)
==3588==    by 0x8296D63: ssl23_client_hello (s23_clnt.c:594)
==3588==    by 0x829621C: ssl23_connect (s23_clnt.c:217)
==3588==    by 0x82A785C: SSL_do_handshake (ssl_lib.c:2564)
==3588==    by 0x82B3C22: ssl_ctrl (bio_ssl.c:423)
==3588==    by 0x82E4552: BIO_ctrl (bio_lib.c:370)
==3588==    by 0x816C2AA: SSL_Connection_connect(SSL_Connection_s*) (SSL_Connection.cpp:162)
==3588==    by 0x8147C17: Connection_connectToHost (Connection.cpp:48)
==3588==  Address 0x106e8cd3 is 11 bytes inside a block of size 21,848 alloc'd
==3588==    at 0x4028876: malloc (vg_replace_malloc.c:236)
==3588==    by 0x82C898B: default_malloc_ex (mem.c:79)
==3588==    by 0x82C8EAA: CRYPTO_malloc (mem.c:308)
==3588==    by 0x82E349B: BUF_MEM_grow (buffer.c:121)
==3588==    by 0x8296198: ssl23_connect (s23_clnt.c:195)
==3588==    by 0x82A785C: SSL_do_handshake (ssl_lib.c:2564)
==3588==    by 0x82B3C22: ssl_ctrl (bio_ssl.c:423)
==3588==    by 0x82E4552: BIO_ctrl (bio_lib.c:370)
==3588==    by 0x816C2AA: SSL_Connection_connect(SSL_Connection_s*) (SSL_Connection.cpp:162)
==3588==    by 0x8147C17: Connection_connectToHost (Connection.cpp:48)
==3588==  Uninitialised value was created by a heap allocation
==3588==    at 0x4028876: malloc (vg_replace_malloc.c:236)
==3588==    by 0x82C898B: default_malloc_ex (mem.c:79)
==3588==    by 0x82C8EAA: CRYPTO_malloc (mem.c:308)
==3588==    by 0x83568E7: bnrand (bn_rand.c:134)
==3588==    by 0x8356B6E: BN_rand (bn_rand.c:213)
==3588==    by 0x8356DCD: bn_rand_range (bn_rand.c:281)
==3588==    by 0x8356EA9: BN_rand_range (bn_rand.c:299)
==3588==    by 0x82DE894: EC_KEY_generate_key (ec_key.c:271)
==3588==    by 0x8288A4D: ssl3_send_client_key_exchange (s3_clnt.c:2606)
==3588==    by 0x8283BA6: ssl3_connect (s3_clnt.c:416)
==3588==    by 0x82A4CF2: SSL_connect (ssl_lib.c:949)
==3588==    by 0x82975B7: ssl23_get_server_hello (s23_clnt.c:797)
==3588==    by 0x829624A: ssl23_connect (s23_clnt.c:226)
==3588==    by 0x82A785C: SSL_do_handshake (ssl_lib.c:2564)
==3588==    by 0x82B3C22: ssl_ctrl (bio_ssl.c:423)
==3588==    by 0x82E4552: BIO_ctrl (bio_lib.c:370)
==3588==    by 0x816C2AA: SSL_Connection_connect(SSL_Connection_s*) (SSL_Connection.cpp:162)
==3588==    by 0x8147C17: Connection_connectToHost (Connection.cpp:48)

为什么会发生此错误:这些错误看起来都来自 OpenSSL 库?

最佳答案

从 Valgrind 错误消息来看,您的程序似乎正在尝试访问系统调用 (write) 中未初始化或不可寻址的值。

==2803== Syscall param write(buf) points to uninitialised byte(s)
==2803==  Address 0xe9125a8 is 8 bytes inside a block of size 17,584 alloc'd
==2803==  Address 0xe9e6f33 is 11 bytes inside a block of size 21,848 alloc'd

来自 Valgrind (Memcheck)可以找到与此相关的手册以下信息:

It checks all parameters to system calls.

It checks all the direct parameters themselves, whether they are initialised.

Also, if a system call needs to read from a buffer provided by your program, Memcheck checks that the entire buffer is addressable and its contents are initialised.

Also, if the system call needs to write to a user-supplied buffer, Memcheck checks that the buffer is addressable.

After the system call, Memcheck updates its tracked information to precisely reflect any changes in memory state caused by the system call.

您可能希望使用 --track-origins=yes 选项在 Valgrind 中运行您的应用程序以获取未初始化内存使用的更详细信息。你可以查看我之前的 post在 Valgrind 上,以及如何结合使用 GDB/Valgrind 在您的程序报告第一个错误时执行实时调试。

关于c++ - 为什么 OpenSSL 会崩溃?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22851367/

相关文章:

go - 如何使用 Go 在证书中添加 SAN 扩展

ssl - 带有 ECC 客户端证书 key 和 RSA 根证书 key 的 2 向 TLS

c++ - if else 语句的预期表达式错误

c - 从 C 实例化 BSD jail

c++ - 来自模板参数的继承层次

C: UDP 数据包源 Ip 伪造 - 无法接收数据包

c - 模拟编译错误

macos - 如何使用 libssl 安装 Siege?

c++ - GLut.h/osfinfo.c/dbgheap.c/mlock.c 中 0x76fe15de 的未处理异常

java - box2d 中的旋转关节