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;
|
char *memory;
|
||||||
size_t size;
|
size_t size;
|
||||||
|
bool memory_overflow;
|
||||||
|
|
||||||
char *location;
|
char *location;
|
||||||
|
|
||||||
|
@ -533,6 +534,8 @@ static void check_multi_info(ogs_sbi_client_t *client)
|
||||||
|
|
||||||
res = resource->data.result;
|
res = resource->data.result;
|
||||||
if (res == CURLE_OK) {
|
if (res == CURLE_OK) {
|
||||||
|
ogs_log_level_e level = OGS_LOG_DEBUG;
|
||||||
|
|
||||||
response = ogs_sbi_response_new();
|
response = ogs_sbi_response_new();
|
||||||
ogs_assert(response);
|
ogs_assert(response);
|
||||||
|
|
||||||
|
@ -546,7 +549,17 @@ static void check_multi_info(ogs_sbi_client_t *client)
|
||||||
response->h.uri = ogs_strdup(url);
|
response->h.uri = ogs_strdup(url);
|
||||||
ogs_assert(response->h.uri);
|
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);
|
response->status, response->h.method, response->h.uri);
|
||||||
|
|
||||||
if (conn->memory) {
|
if (conn->memory) {
|
||||||
|
@ -557,16 +570,17 @@ static void check_multi_info(ogs_sbi_client_t *client)
|
||||||
ogs_assert(response->http.content_length);
|
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)
|
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
|
} else
|
||||||
ogs_warn("[%d] %s", res, conn->error);
|
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;
|
realsize = size * nmemb;
|
||||||
ptr = ogs_realloc(conn->memory, conn->size + realsize + 1);
|
ptr = ogs_realloc(conn->memory, conn->size + realsize + 1);
|
||||||
if(!ptr) {
|
if(!ptr) {
|
||||||
ogs_fatal("not enough memory (realloc returned NULL)");
|
conn->memory_overflow = true;
|
||||||
ogs_assert_if_reached();
|
|
||||||
|
ogs_error("Overflow : conn->size[%d], realsize[%d]",
|
||||||
|
(int)conn->size, (int)realsize);
|
||||||
|
ogs_log_hexdump(OGS_LOG_ERROR, contents, realsize);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -82,6 +82,7 @@ typedef struct ogs_sbi_stream_s {
|
||||||
|
|
||||||
int32_t stream_id;
|
int32_t stream_id;
|
||||||
ogs_sbi_request_t *request;
|
ogs_sbi_request_t *request;
|
||||||
|
bool memory_overflow;
|
||||||
|
|
||||||
ogs_sbi_session_t *session;
|
ogs_sbi_session_t *session;
|
||||||
} ogs_sbi_stream_t;
|
} ogs_sbi_stream_t;
|
||||||
|
@ -791,12 +792,23 @@ static int on_frame_recv(nghttp2_session *session,
|
||||||
case NGHTTP2_DATA:
|
case NGHTTP2_DATA:
|
||||||
/* HEADERS or DATA frame with +END_STREAM flag */
|
/* HEADERS or DATA frame with +END_STREAM flag */
|
||||||
if (frame->hd.flags & NGHTTP2_FLAG_END_STREAM) {
|
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) {
|
if (request->http.content_length && request->http.content) {
|
||||||
ogs_debug("RECEIVED: %d", (int)request->http.content_length);
|
ogs_log_message(level, 0,
|
||||||
ogs_debug("%s", request->http.content);
|
"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) {
|
if (server->cb(request, stream) != OGS_OK) {
|
||||||
|
@ -967,22 +979,29 @@ static int on_data_chunk_recv(nghttp2_session *session, uint8_t flags,
|
||||||
ogs_assert(len);
|
ogs_assert(len);
|
||||||
|
|
||||||
if (request->http.content == NULL) {
|
if (request->http.content == NULL) {
|
||||||
request->http.content_length = len;
|
ogs_assert(request->http.content_length == 0);
|
||||||
request->http.content =
|
ogs_assert(offset == 0);
|
||||||
(char*)ogs_malloc(request->http.content_length + 1);
|
|
||||||
ogs_assert(request->http.content);
|
request->http.content = (char*)ogs_malloc(len + 1);
|
||||||
} else {
|
} else {
|
||||||
offset = request->http.content_length;
|
ogs_assert(request->http.content_length != 0);
|
||||||
if ((request->http.content_length + len) > OGS_HUGE_LEN) {
|
|
||||||
|
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]",
|
ogs_error("Overflow : Content-Length[%d], len[%d]",
|
||||||
(int)request->http.content_length, (int)len);
|
(int)request->http.content_length, (int)len);
|
||||||
ogs_assert_if_reached();
|
ogs_log_hexdump(OGS_LOG_ERROR, data, len);
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
offset = request->http.content_length;
|
||||||
request->http.content_length += len;
|
request->http.content_length += len;
|
||||||
request->http.content = (char *)ogs_realloc(
|
|
||||||
request->http.content, request->http.content_length + 1);
|
|
||||||
ogs_assert(request->http.content);
|
|
||||||
}
|
|
||||||
|
|
||||||
memcpy(request->http.content + offset, data, len);
|
memcpy(request->http.content + offset, data, len);
|
||||||
request->http.content[request->http.content_length] = '\0';
|
request->http.content[request->http.content_length] = '\0';
|
||||||
|
|
Loading…
Reference in New Issue