Skip to content

Double free in Http2ConnectionState::release_stream #4258

@zizhong

Description

@zizhong

Recently, we encountered a type of crashes in Http2ConnectionState::release_stream.
After digging into it more, I think it is already fixed with PR #4147 and PR #4178. Thanks, @shinrich.

The backtrace is

#6  0x00000000004ada7e in crash_logger_invoke (signo=11, info=0x2b676c50f730, ctx=0x2b676c50f600) at Crash.cc:169
#7  <signal handler called>
#8  0x0000000000000100 in ?? ()
#9  0x0000000000609d72 in Http2ConnectionState::release_stream (this=this@entry=0x2b6814d50280, stream=stream@entry=0x2b68625b9280) at Http2ConnectionState.cc:1078
#10 0x00000000005f9c5e in Http2Stream::destroy (this=0x2b68625b9280) at Http2Stream.cc:665
#11 0x00000000005fd6e7 in Http2Stream::main_event_handler (this=0x2b68625b9280, event=104, edata=<optimized out>) at Http2Stream.cc:126
#12 0x0000000000773b80 in handleEvent (data=0x2b67edaadce0, event=104, this=<optimized out>) at I_Continuation.h:153
#13 EThread::process_event (this=0x2b6769a08000, e=0x2b67edaadce0, calling_code=104) at UnixEThread.cc:148
#14 0x000000000077483b in EThread::execute (this=0x2b6769a08000) at UnixEThread.cc:202
#15 0x000000000077362a in spawn_thread_internal (a=0x2b676773bb20) at Thread.cc:86
#16 0x00002b6764383dc5 in start_thread () from /lib64/libpthread.so.0
#17 0x00002b676541f76d in clone () from /lib64/libc.so.6

The double free happens as follows

Http2ConnectionState::release_stream -> 
	ProxyClientSession::handle_api_return->
		SSLNetVConnection::do_io_close->
			close_UnixNetVConnection() // free the vc

		Http2ClientSession::release_netvc() will write it again. (use after free)

		Http2ClientSession::free()
			if (client_vc) {
    				release_netvc(); // (use after free again)
    				client_vc->do_io_close()
    					SSLNetVConnection::do_io_close->
    						close_UnixNetVConnection()  // double free the vc
    				client_vc = nullptr
    			}

After the PR #4147 and PR #4178,
all the release_netvc() is removed.
vc->do_io_close() is removed from ProxyClientSession::handle_api_return

so the workflow will be:

	Http2ConnectionState::release_stream -> 
		ProxyClientSession::handle_api_return->
			Http2ClientSession::free()
				if (client_vc) {
					client_vc->do_io_close()
						SSLNetVConnection::do_io_close->
							close_UnixNetVConnection() // free the vc
					client_vc = nullptr
				}

Though it's fixed, I think keeping this crash on record could be helpful if some others observe
the same issue.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions