Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Segmentation Fault When Using HTTPS #440

Closed
salmangano opened this issue Jul 13, 2020 · 7 comments · Fixed by #483
Closed

Segmentation Fault When Using HTTPS #440

salmangano opened this issue Jul 13, 2020 · 7 comments · Fixed by #483
Assignees
Labels
Milestone

Comments

@salmangano
Copy link

To isolate the problem I simply used the sample program provided in the docs with small modifications (see below). The program seg faults as soon as the web browser attempts to connect. Partial stack below.

We used a self-signed cert created by the following:

openssl genrsa -out server.key 2048
openssl req -new -key server.key -out server.csr
openssl x509 -req -days 3650 -in server.csr -signkey server.key -out server.crt
openssl dhparam -out dh2048.pem 2048

We changed the port to 55580 to avoid using privileged ports. We also but our crypto files in a .ssh dir:

[bbxadm@ny5-pr-bbxntr-01 algoframe]$ ls -l .ssh/
total 3
-rw-r--r-- 1 bbxadm greenshift 424 Jun 12 12:08 dh2048.pem
-rw-r--r-- 1 bbxadm greenshift 201 Jun 11 15:49 dh768.pem
-rw-r--r-- 1 bbxadm greenshift 1440 Jun 12 11:59 server.crt
-rw-r--r-- 1 bbxadm greenshift 1115 Jun 12 11:59 server.csr
-rw------- 1 bbxadm greenshift 1679 Jun 12 10:26 server.key

The modified sample code is:

#include
#include
#include

using namespace std;
using namespace restbed;

void get_method_handler( const shared_ptr< Session > session )
{
session->close( OK, "Hello, World!", { { "Content-Length", "13" }, { "Connection", "close" } } );
}

int main( const int, const char** )
{
auto resource = make_shared< Resource >( );
resource->set_path( "/resource" );
resource->set_method_handler( "GET", get_method_handler );

auto ssl_settings = make_shared< SSLSettings >( );
ssl_settings->set_http_disabled( true );
ssl_settings->set_private_key( restbed::Uri( "https://protect-us.mimecast.com/s/JglWCYEZyETA3OwohGVjym?domain=.ssh" ) );
ssl_settings->set_certificate( restbed::Uri( "https://protect-us.mimecast.com/s/YmPTCZ6gz6tQM20nuK-mXZ?domain=.ssh" ) );
ssl_settings->set_temporary_diffie_hellman( restbed::Uri( "https://protect-us.mimecast.com/s/0SL7C1wMGwtqp5lwcXgOH1?domain=.ssh" ) );
ssl_settings->set_port(55580) ;
auto settings = make_shared< Settings >( );
settings->set_ssl_settings( ssl_settings );

Service service;
service.publish( resource );
service.start( settings );

return EXIT_SUCCESS;

}

Program received signal SIGSEGV, Segmentation fault.
0x00007ffff7a6cf0e in asio::basic_io_object<asio::detail::reactive_socket_serviceasio::ip::tcp, true>::get_service() () from /usr/local/lib/librestbed.so.4
Missing separate debuginfos, use: debuginfo-install glibc-2.17-260.el7.x86_64 libgcc-4.8.5-36.el7.x86_64 libstdc++-4.8.5-36.el7.x86_64
(gdb) bt
#0 0x00007ffff7a6cf0e in asio::basic_io_object<asio::detail::reactive_socket_serviceasio::ip::tcp, true>::get_service() () from /usr/local/lib/librestbed.so.4
#1 0x00007ffff7ac1011 in asio::basic_socketasio::ip::tcp::native_handle() () from /usr/local/lib/librestbed.so.4
#2 0x00007ffff7a8454a in restbed::detail::SocketImpl::set_keep_alive(unsigned int, unsigned int, unsigned int) () from /usr/local/lib/librestbed.so.4
#3 0x00007ffff7a57bf5 in restbed::detail::ServiceImpl::create_ssl_session(std::shared_ptr<asio::ssl::stream<asio::basic_stream_socketasio::ip::tcp > > const&, std::error_code const&) const::{lambda(std::error_code const&)#1}::operator()(std::error_code const&) const () from /usr/local/lib/librestbed.so.4
#4 0x00007ffff7a5f3f1 in void asio::ssl::detail::handshake_op::call_handler<restbed::detail::ServiceImpl::create_ssl_session(std::shared_ptr<asio::ssl::stream<asio::basic_stream_socketasio::ip::tcp > > const&, std::error_code const&) const::{lambda(std::error_code const&)#1}>(restbed::detail::ServiceImpl::create_ssl_session(std::shared_ptr<asio::ssl::stream<asio::basic_stream_socketasio::ip::tcp > > const&, std::error_code const&) const::{lambda(std::error_code const&)#1}&, std::error_code const&, unsigned long const&) const
() from /usr/local/lib/librestbed.so.4
#5 0x00007ffff7a5ec66 in asio::ssl::detail::io_op<asio::basic_stream_socketasio::ip::tcp, asio::ssl::detail::handshake_op, restbed::detail::ServiceImpl::create_ssl_session(std::shared_ptr<asio::ssl::stream<asio::basic_stream_socketasio::ip::tcp > > const&, std::error_code const&) const::{lambda(std::error_code const&)#1}>::operator()(std::error_code, unsigned long, int) () from /usr/local/lib/librestbed.so.4
#6 0x00007ffff7a5fd2e in asio::detail::write_op<asio::basic_stream_socketasio::ip::tcp, asio::mutable_buffer, asio::mutable_buffer const*, asio::detail::transfer_all_t, asio::ssl::detail::io_op<asio::basic_stream_socketasio::ip::tcp, asio::ssl::detail::handshake_op, restbed::detail::ServiceImpl::create_ssl_session(std::shared_ptr<asio::ssl::stream<asio::basic_stream_socketasio::ip::tcp > > const&, std::error_code const&) const::{lambda(std::error_code const&)#1}> >::operator()(std::error_code const&, unsigned long, int) ()
from /usr/local/lib/librestbed.so.4
#7 0x00007ffff7a6150f in asio::detail::binder2<asio::detail::write_op<asio::basic_stream_socketasio::ip::tcp, asio::mutable_buffer, asio::mutable_buffer const*, asio::detail::transfer_all_t, asio::ssl::detail::io_op<asio::basic_stream_socketasio::ip::tcp, asio::ssl::detail::handshake_op, restbed::detail::ServiceImpl::create_ssl_session(std::shared_ptr<asio::ssl::stream<asio::basic_stream_socketasio::ip::tcp > > const&, std::error_code const&) const::{lambda(std::error_code const&)#1}> >, std::error_code, unsigned long>::operator()() () from /usr/local/lib/librestbed.so.4

Build En/Runtime Below

OS: Linux version 3.10.0-957.el7.x86_64
Compiler:
$ gcc --version
gcc (GCC) 7.3.1 20180303 (Red Hat 7.3.1-5)
Copyright (C) 2017 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

ASIO version: #define ASIO_VERSION 101202 // 1.12.2
OpenSSL Version: $ openssl
OpenSSL> version
OpenSSL 1.1.1g 21 Apr 2020

[bbxadm@ny5-pr-bbxntr-01 algoframe]$ ldd bin/httpsTest
linux-vdso.so.1 => (0x00007fff5991e000)
librestbed.so.4 => /usr/local/lib/librestbed.so.4 (0x00007fce5895b000)
libcrypto.so.1.1 => /lib64/libcrypto.so.1.1 (0x00007fce58472000)
libstdc++.so.6 => /lib64/libstdc++.so.6 (0x00007fce5816b000)
libm.so.6 => /lib64/libm.so.6 (0x00007fce57e69000)
libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x00007fce57c53000)
libc.so.6 => /lib64/libc.so.6 (0x00007fce57886000)
libssl.so.1.1 => /lib64/libssl.so.1.1 (0x00007fce575f4000)
libpthread.so.0 => /lib64/libpthread.so.0 (0x00007fce573d8000)
/lib64/ld-linux-x86-64.so.2 (0x00007fce58f12000)
libdl.so.2 => /lib64/libdl.so.2 (0x00007fce571d4000)

[bbxadm@ny5-pr-bbxntr-01 algoframe]$ ldd /usr/local/lib/librestbed.so.4
linux-vdso.so.1 => (0x00007fff04774000)
libssl.so.1.1 => /lib64/libssl.so.1.1 (0x00007fede5b91000)
libcrypto.so.1.1 => /lib64/libcrypto.so.1.1 (0x00007fede56a8000)
libstdc++.so.6 => /lib64/libstdc++.so.6 (0x00007fede53a1000)
libm.so.6 => /lib64/libm.so.6 (0x00007fede509f000)
libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x00007fede4e89000)
libpthread.so.0 => /lib64/libpthread.so.0 (0x00007fede4c6d000)
libc.so.6 => /lib64/libc.so.6 (0x00007fede48a0000)
/lib64/ld-linux-x86-64.so.2 (0x00007fede63da000)
libdl.so.2 => /lib64/libdl.so.2 (0x00007fede469c000)

Sal Mangano
Software Architect
Schonfeld Strategic Advisors LLC
T: 212-909-1560 | M: 516-272-2487
E: smangano@schonfeld.com
460 Park Ave | New York, NY 10022

@salmangano
Copy link
Author

Being that several days have passed with crickets I decided to debug your (seemingly ill conceived) SocketImpl. I found that the code assumes m_socket is not null in SocketImpl::set_keep_alive. It will be null, I assume, if ssl_settings->set_http_disabled( true ); is used as in my example above.

For now I addressed my modifying the code to return if m_socket is null.

FWIW, I say "seemingly ill conceived" because it strikes me this code is over complicated by managing both m_socket and m_ssl_socket and needing to consider that one or the other might be null. Clearly it led to a bug in this case and conceivably there could be more like this but I'll leave it to you to inspect.

@Plurilogic
Copy link

I am testing RestBed and I have the same problem.. what is the solution ?

@salmangano
Copy link
Author

@Plurilogic You can modify the code as I did:

void SocketImpl::set_keep_alive( const uint32_t start, const uint32_t interval, const uint32_t cnt) { (void) cnt; (void) start; (void) interval; if (!m_socket) { return ; } ...

or not use ssl_settings->set_http_disabled( true ); but this second solution is just a theory I have not tested.

@salmangano
Copy link
Author

salmangano commented Aug 25, 2020

The fact that this is a reproducible bug and there has been no response from corvusoft is not a good sign. I just went too far down the road with restbed to switch to another solution.

@Plurilogic
Copy link

thanks !

The second solutions works, but yours is better

@myke-80
Copy link

myke-80 commented Jan 18, 2021

Found the same issue this morning, I had to set the keepalive to false

settings->set_keep_alive( false );

since commenting set_http_disabled(true) in my code was not enough to avoid segmentation fault.

@ben-crowhurst
Copy link
Member

Will take a look at this for the 4.8 release.

The power of Open Source solutions is it enables everyone to contribute. If you require commercial-grade support you can contact Corvusoft. Alternatively, you can create a PR with a fix.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment