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

lib: nghttp2: backport upstream security fix #9052

Merged
merged 1 commit into from
Jul 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion lib/nghttp2/lib/includes/nghttp2/nghttp2.h
Original file line number Diff line number Diff line change
Expand Up @@ -440,7 +440,12 @@ typedef enum {
* exhaustion on server side to send these frames forever and does
* not read network.
*/
NGHTTP2_ERR_FLOODED = -904
NGHTTP2_ERR_FLOODED = -904,
/**
* When a local endpoint receives too many CONTINUATION frames
* following a HEADER frame.
*/
NGHTTP2_ERR_TOO_MANY_CONTINUATIONS = -905,
} nghttp2_error;

/**
Expand Down
2 changes: 2 additions & 0 deletions lib/nghttp2/lib/nghttp2_helper.c
Original file line number Diff line number Diff line change
Expand Up @@ -336,6 +336,8 @@ const char *nghttp2_strerror(int error_code) {
"closed";
case NGHTTP2_ERR_TOO_MANY_SETTINGS:
return "SETTINGS frame contained more than the maximum allowed entries";
case NGHTTP2_ERR_TOO_MANY_CONTINUATIONS:
return "Too many CONTINUATION frames following a HEADER frame";
default:
return "Unknown error code";
}
Expand Down
7 changes: 7 additions & 0 deletions lib/nghttp2/lib/nghttp2_session.c
Original file line number Diff line number Diff line change
Expand Up @@ -496,6 +496,7 @@ static int session_new(nghttp2_session **session_ptr,
(*session_ptr)->max_send_header_block_length = NGHTTP2_MAX_HEADERSLEN;
(*session_ptr)->max_outbound_ack = NGHTTP2_DEFAULT_MAX_OBQ_FLOOD_ITEM;
(*session_ptr)->max_settings = NGHTTP2_DEFAULT_MAX_SETTINGS;
(*session_ptr)->max_continuations = NGHTTP2_DEFAULT_MAX_CONTINUATIONS;

if (option) {
if ((option->opt_set_mask & NGHTTP2_OPT_NO_AUTO_WINDOW_UPDATE) &&
Expand Down Expand Up @@ -6778,6 +6779,8 @@ ssize_t nghttp2_session_mem_recv(nghttp2_session *session, const uint8_t *in,
}
}
session_inbound_frame_reset(session);

session->num_continuations = 0;
}
break;
}
Expand Down Expand Up @@ -6899,6 +6902,10 @@ ssize_t nghttp2_session_mem_recv(nghttp2_session *session, const uint8_t *in,
}
#endif /* DEBUGBUILD */

if (++session->num_continuations > session->max_continuations) {
return NGHTTP2_ERR_TOO_MANY_CONTINUATIONS;
}

readlen = inbound_frame_buf_read(iframe, in, last);
in += readlen;

Expand Down
10 changes: 10 additions & 0 deletions lib/nghttp2/lib/nghttp2_session.h
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,10 @@ typedef struct {
#define NGHTTP2_DEFAULT_STREAM_RESET_BURST 1000
#define NGHTTP2_DEFAULT_STREAM_RESET_RATE 33

/* The default max number of CONTINUATION frames following an incoming
HEADER frame. */
#define NGHTTP2_DEFAULT_MAX_CONTINUATIONS 8

/* Internal state when receiving incoming frame */
typedef enum {
/* Receiving frame header */
Expand Down Expand Up @@ -290,6 +294,12 @@ struct nghttp2_session {
size_t max_send_header_block_length;
/* The maximum number of settings accepted per SETTINGS frame. */
size_t max_settings;
/* The maximum number of CONTINUATION frames following an incoming
HEADER frame. */
size_t max_continuations;
/* The number of CONTINUATION frames following an incoming HEADER
frame. This variable is reset when END_HEADERS flag is seen. */
size_t num_continuations;
/* Next Stream ID. Made unsigned int to detect >= (1 << 31). */
uint32_t next_stream_id;
/* The last stream ID this session initiated. For client session,
Expand Down
Loading