BIO_do_connect вызывает segfault - PullRequest
       0

BIO_do_connect вызывает segfault

0 голосов
/ 03 ноября 2019

Сводка

Когда мой код вызывает BIO_do_connect, он возвращается к началу вызывающей его функции и затем segfaults.

Что пробовал

Отладчик, 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;
}

Ожидаемый результат:

  • «Соединение вызывается» должно отображаться только один раз.
  • В программе не должно быть ошибок сегментации.

Фактический вывод:

./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)

Вывод отладчика и обратная трассировка:

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 ?? ()

1 Ответ

0 голосов
/ 03 ноября 2019

Ваша функция connect() скрывает стандартную функцию библиотеки neworking с тем же именем, которое OpenSSL вызывает для установления фактического TCP-соединения, но вместо того, чтобы получить библиотеку, она вызывает ваше.

Переименуйте вашфункция (скажем, do_connect()), поэтому она не будет конфликтовать с библиотекой.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...