We have released nghttp2
v1.55.1.
This release includes security advisory.
Security Advisory
CVE-2023-35945: HTTP/2 memory leak in nghttp2 codec
For more information, read the security advisory.
This CVE was filed by envoyproxy/envoy project, and has already been
made public, and we did not take usual security procedure. See below
why.
lib
This release fixes memory leak that happens when PUSH_PROMISE or
HEADERS frame cannot be sent, and nghttp2_on_stream_close_callback
fails with a fatal error. For example, if GOAWAY frame has been
received, a HEADERS frame that opens new stream cannot be sent.
This issue has already been made public via
CVE-2023-35945
issued by envoyproxy/envoy project. During embargo period,
the patch to fix this bug
was accidentally submitted to nghttp2/nghttp2 repository. And
they decided to disclose CVE early. I was notified just 1.5 hours
before disclosure. I had no time to respond.
PoC described in CVE is quite simple, but I think it is not enough to
trigger this bug. While it is true that receiving GOAWAY prevents a
client from opening new stream, and nghttp2 enters error handling
branch, in order to cause the memory leak,
nghttp2_session_close_stream
function must return a fatal error.
nghttp2 defines 2 fatal error codes:
NGHTTP2_ERR_NOMEM
NGHTTP2_ERR_CALLBACK_FAILURE
NGHTTP2_ERR_NOMEM
, as its name suggests, indicates out of memory.
It is unlikely that a process gets short of memory with this simple
PoC scenario unless application does something memory heavy
processing.
NGHTTP2_ERR_CALLBACK_FAILURE
is returned from application defined
callback function (nghttp2_on_stream_close_callback
, in this case),
which indicates something fatal happened inside a callback, and a
connection must be closed immediately without any further action. As
nghttp2_on_stream_close_error_callback
documentation says, any error
code other than 0 or NGHTTP2_ERR_CALLBACK_FAILURE
is treated as
fatal error code. More specifically, it is treated as if
NGHTTP2_ERR_CALLBACK_FAILURE
is returned. I guess that envoy
returns NGHTTP2_ERR_CALLBACK_FAILURE
or other error code which is
translated into NGHTTP2_ERR_CALLBACK_FAILURE
.