簡體   English   中英

BIO_do_connect 導致段錯誤

[英]BIO_do_connect causes segfault

概括

當我的代碼調用 BIO_do_connect 時,它會跳回到調用它的 function 的開頭,然后出現段錯誤。

什么嘗試

調試器,Valgrind,更改代碼

// compiled with:
// gcc -g -O0 -Wall -Wextra -o sslex sslex_main.c -fstack-protector -lssl -lcrypto
#include <stdio.h>
#include <string.h>
#include <openssl/ssl.h>
#include <openssl/bio.h>
#include <openssl/err.h>

// BIO handles communication including files and sockets.
static BIO* g_bio = NULL;
// holds SSL connection information
static SSL_CTX* g_sslContext = NULL;
char* g_trustedStore = "certs/trusted.pem";

void initialize() {
    SSL_load_error_strings();
    ERR_load_BIO_strings();
    OpenSSL_add_all_algorithms();
}

int connect(char* hostnamePort) {
    SSL* sslp = NULL;
    BIO* out = NULL;
    printf("Connect called\n");
    printf("Connecting... to %s\n", hostnamePort);

    g_sslContext = SSL_CTX_new(TLS_client_method());

    // load trusted certificate store
    if (! SSL_CTX_load_verify_locations(g_sslContext, g_trustedStore, NULL)) {
        fprintf(stderr, "Failure loading certificats from trusted store %s!\n", g_trustedStore);
        fprintf(stderr, "Error: %s\n", ERR_reason_error_string(ERR_get_error()));
        return -1;
    }

    g_bio = BIO_new_ssl_connect(g_sslContext);
    if (g_bio == NULL) {
        fprintf(stderr, "Error cannot get BSD Input/Output\n");
        return -1;
    }
    // retrieve ssl pointer of the BIO
    BIO_get_ssl(g_bio, &sslp);
    if (sslp == NULL) {
        fprintf(stderr, "Could not locate SSL pointer\n");
        fprintf(stderr, "Error: %s\n", ERR_reason_error_string(ERR_get_error()));
        return -1;
    }

    // if server wants a new handshake, handle that in the background
    SSL_set_mode(sslp, SSL_MODE_AUTO_RETRY);

    // attempt to connect
    BIO_set_conn_hostname(g_bio, hostnamePort);

    out = BIO_new_fp(stdout, BIO_NOCLOSE);
    printf("Connecting to: %s\n", BIO_get_conn_hostname(g_bio));

    // THIS LINE CAUSES STACK SMASH
    if (BIO_do_connect(g_bio) <= 0) { // BUGGY LINE
        fprintf(stderr, "Error cannot connect to %s\n", hostnamePort);
        fprintf(stderr, "Error: %s\n", ERR_reason_error_string(ERR_get_error()));
        BIO_free_all(g_bio);
        SSL_CTX_free(g_sslContext);
        return -1;
    }
    return -1;
}

void close_connection() {
    BIO_free_all(g_bio);
    SSL_CTX_free(g_sslContext);
}

int main(int argc, char* argv[]) {
    char* hostnamePort = argv[1];
    initialize();
    if (connect(hostnamePort) != 0)
        return 0;
    printf("Done connecting. doing operation\n");
    close_connection();
    return 0;
}

預期結果:

  • “連接調用”應該只顯示一次。
  • 程序不應該出現Segmentation fault。

實際 Output:

./sslex 192.168.11.141
Connect called
Connecting... to 192.168.11.141
Connecting to: 192.168.11.141
Connect called
Segmentation fault (core dumped)

調試器 Output 和回溯:

Starting program: sslex 192.168.11.141
warning: Probes-based dynamic linker interface failed.
Reverting to original interface.

Connect called
Connecting... to 192.168.11.141
Connecting to: 192.168.11.141

Breakpoint 3, connect (hostnamePort=0x7fffffffe9db "192.168.11.141") at sslex_main.c:57
57      if (BIO_do_connect(g_bio) <= 0) { // BUGGY LINE
(gdb) bt
#0  connect (hostnamePort=0x7fffffffe9db "192.168.11.141") at sslex_main.c:57
#1  0x000055555555503a in main (argc=2, argv=0x7fffffffe698) at sslex_main.c:75
(gdb) s
Connect called

Program received signal SIGSEGV, Segmentation fault.
0x00007ffff733d646 in ?? ()
(gdb) bt
#0  0x00007ffff733d646 in ?? ()
#1  0x00007ffff72e94d3 in ?? ()
#2  0x0000000000000000 in ?? ()

Your function connect() is hiding the standard neworking library function of the same name that OpenSSL is calling to make the actual TCP connection, but instead of getting the library one, it's calling yours.

重命名您的 function (例如,改為do_connect() ),這樣它就不會與庫中的那個沖突。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM