Reputation: 3
Summary
When my code calls BIO_do_connect it jumps back to the start of the function that called it and then segfaults.
What Tried
Debugger, Valgrind, changing code
// 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;
}
Expected Result:
Actual 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)
Debugger Output and Backtrace:
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 ?? ()
Upvotes: 0
Views: 259
Reputation: 4247
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.
Rename your function (say, to do_connect()
) so it won't clash with the one from the library.
Upvotes: 1