Skip to content
Permalink
Browse files Browse the repository at this point in the history
Fixed HTTP2 crashes for random JSON data (#1769)
  • Loading branch information
acetcom committed Sep 25, 2022
1 parent c2f6a02 commit 724fa56
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 28 deletions.
40 changes: 29 additions & 11 deletions lib/sbi/client.c
Expand Up @@ -44,6 +44,7 @@ typedef struct connection_s {

char *memory;
size_t size;
bool memory_overflow;

char *location;

Expand Down Expand Up @@ -533,6 +534,8 @@ static void check_multi_info(ogs_sbi_client_t *client)

res = resource->data.result;
if (res == CURLE_OK) {
ogs_log_level_e level = OGS_LOG_DEBUG;

response = ogs_sbi_response_new();
ogs_assert(response);

Expand All @@ -546,7 +549,17 @@ static void check_multi_info(ogs_sbi_client_t *client)
response->h.uri = ogs_strdup(url);
ogs_assert(response->h.uri);

ogs_debug("[%d:%s] %s",
if (content_type)
ogs_sbi_header_set(response->http.headers,
OGS_SBI_CONTENT_TYPE, content_type);
if (conn->location)
ogs_sbi_header_set(response->http.headers,
OGS_SBI_LOCATION, conn->location);

if (conn->memory_overflow == true)
level = OGS_LOG_ERROR;

ogs_log_message(level, 0, "[%d:%s] %s",
response->status, response->h.method, response->h.uri);

if (conn->memory) {
Expand All @@ -557,16 +570,17 @@ static void check_multi_info(ogs_sbi_client_t *client)
ogs_assert(response->http.content_length);
}

ogs_debug("RECEIVED[%d]", (int)response->http.content_length);
ogs_log_message(level, 0, "RECEIVED[%d]",
(int)response->http.content_length);
if (response->http.content_length && response->http.content)
ogs_debug("%s", response->http.content);
ogs_log_message(level, 0, "%s", response->http.content);

if (conn->memory_overflow == true) {
ogs_sbi_response_free(response);
connection_remove(conn);
break;
}

if (content_type)
ogs_sbi_header_set(response->http.headers,
OGS_SBI_CONTENT_TYPE, content_type);
if (conn->location)
ogs_sbi_header_set(response->http.headers,
OGS_SBI_LOCATION, conn->location);
} else
ogs_warn("[%d] %s", res, conn->error);

Expand Down Expand Up @@ -727,8 +741,12 @@ static size_t write_cb(void *contents, size_t size, size_t nmemb, void *data)
realsize = size * nmemb;
ptr = ogs_realloc(conn->memory, conn->size + realsize + 1);
if(!ptr) {
ogs_fatal("not enough memory (realloc returned NULL)");
ogs_assert_if_reached();
conn->memory_overflow = true;

ogs_error("Overflow : conn->size[%d], realsize[%d]",
(int)conn->size, (int)realsize);
ogs_log_hexdump(OGS_LOG_ERROR, contents, realsize);

return 0;
}

Expand Down
53 changes: 36 additions & 17 deletions lib/sbi/nghttp2-server.c
Expand Up @@ -82,6 +82,7 @@ typedef struct ogs_sbi_stream_s {

int32_t stream_id;
ogs_sbi_request_t *request;
bool memory_overflow;

ogs_sbi_session_t *session;
} ogs_sbi_stream_t;
Expand Down Expand Up @@ -791,12 +792,23 @@ static int on_frame_recv(nghttp2_session *session,
case NGHTTP2_DATA:
/* HEADERS or DATA frame with +END_STREAM flag */
if (frame->hd.flags & NGHTTP2_FLAG_END_STREAM) {
ogs_log_level_e level = OGS_LOG_DEBUG;

ogs_debug("[%s] %s", request->h.method, request->h.uri);
if (stream->memory_overflow == true)
level = OGS_LOG_ERROR;

ogs_log_message(level, 0,
"[%s] %s", request->h.method, request->h.uri);

if (request->http.content_length && request->http.content) {
ogs_debug("RECEIVED: %d", (int)request->http.content_length);
ogs_debug("%s", request->http.content);
ogs_log_message(level, 0,
"RECEIVED: %d", (int)request->http.content_length);
ogs_log_message(level, 0, "%s", request->http.content);
}

if (stream->memory_overflow == true) {
ogs_error("[DROP] Overflow");
break;
}

if (server->cb(request, stream) != OGS_OK) {
Expand Down Expand Up @@ -967,23 +979,30 @@ static int on_data_chunk_recv(nghttp2_session *session, uint8_t flags,
ogs_assert(len);

if (request->http.content == NULL) {
request->http.content_length = len;
request->http.content =
(char*)ogs_malloc(request->http.content_length + 1);
ogs_assert(request->http.content);
ogs_assert(request->http.content_length == 0);
ogs_assert(offset == 0);

request->http.content = (char*)ogs_malloc(len + 1);
} else {
offset = request->http.content_length;
if ((request->http.content_length + len) > OGS_HUGE_LEN) {
ogs_error("Overflow : Content-Length[%d], len[%d]",
(int)request->http.content_length, (int)len);
ogs_assert_if_reached();
}
request->http.content_length += len;
request->http.content = (char *)ogs_realloc(
request->http.content, request->http.content_length + 1);
ogs_assert(request->http.content);
ogs_assert(request->http.content_length != 0);

request->http.content = (char*)ogs_realloc(
request->http.content, request->http.content_length + len + 1);
}

if (!request->http.content) {
stream->memory_overflow = true;

ogs_error("Overflow : Content-Length[%d], len[%d]",
(int)request->http.content_length, (int)len);
ogs_log_hexdump(OGS_LOG_ERROR, data, len);

return 0;
}

offset = request->http.content_length;
request->http.content_length += len;

memcpy(request->http.content + offset, data, len);
request->http.content[request->http.content_length] = '\0';

Expand Down

0 comments on commit 724fa56

Please sign in to comment.