forked from acouzens/open5gs
Fixed HTTP2 crashes for random JSON data (#1769)
This commit is contained in:
parent
c2f6a020a7
commit
724fa56843
|
@ -44,6 +44,7 @@ typedef struct connection_s {
|
|||
|
||||
char *memory;
|
||||
size_t size;
|
||||
bool memory_overflow;
|
||||
|
||||
char *location;
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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) {
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
@ -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) {
|
||||
|
@ -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';
|
||||
|
||||
|
|
Loading…
Reference in New Issue