为什么OpenSSL崩溃?

时间:2014-04-04 00:25:11

标签: 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-origin:

==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库?

1 个答案:

答案 0 :(得分:2)

从Valgrind错误消息中看起来您的程序试图在系统调用中访问未初始化或不可寻址的值(写入)。

==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)手册中可以找到以下信息:

  

它检查系统调用的所有参数。

     

它会检查所有直接参数本身,无论它们是什么   初始化。

     

此外,如果系统调用需要从您提供的缓冲区中读取   程序,Memcheck检查整个缓冲区是否可寻址   内容已初始化。

     

此外,如果系统调用需要写入用户提供的缓冲区,   Memcheck检查缓冲区是否可寻址。

     

系统调用后,Memcheck将其跟踪信息更新为   准确反映系统引起的内存状态的任何变化   调用

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