mirror of
https://github.com/open5gs/open5gs.git
synced 2026-04-26 10:30:41 +00:00
sbi/nrf: This patch improves robustness of SBI client creation, HTTP parsing,
and NRF NFProfile validation by adding defensive checks and safer memory handling. Key changes: 1) Prevent client creation without endpoint information - Added error logging when NF instance lacks FQDN/IP endpoint data. - Avoids creating invalid SBI clients with incomplete connectivity info. 2) Enforce query parameter limits - Added explicit bounds check against MAX_NUM_OF_PARAM_IN_QUERY. - Returns HTTP 400 instead of triggering fatal assertion. - Prevents potential DoS via excessive query parameters. 3) Safer HTTP body memory handling - Introduced temporary buffer for malloc/realloc results. - Prevents loss of original pointer on realloc failure. - Returns NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE on overflow. - Improves resilience against large/fragmented payload attacks. 4) Validate NFProfile endpoint presence during registration - Rejects NFProfile lacking FQDN, IPv4, and IPv6 addresses. - Returns HTTP 400 with explicit error message. - Prevents NRF from storing unreachable NF instances. Overall, this patch strengthens SBI stability and protects against resource exhaustion, malformed requests, and invalid NF registrations. Issues: #4243, #4244, #4245
This commit is contained in:
parent
b3169c8ee9
commit
2575c49803
3 changed files with 37 additions and 11 deletions
|
|
@ -2052,7 +2052,8 @@ static ogs_sbi_client_t *nf_instance_find_client(
|
|||
return NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else
|
||||
ogs_error("No endpoint info, skip client creation");
|
||||
|
||||
return client;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1397,6 +1397,21 @@ static int on_header(nghttp2_session *session, const nghttp2_frame *frame,
|
|||
|
||||
j = 0;
|
||||
while(params[j].key && params[j].val) {
|
||||
if (j >= MAX_NUM_OF_PARAM_IN_QUERY) {
|
||||
ogs_error("Too many query params (max=%d)",
|
||||
MAX_NUM_OF_PARAM_IN_QUERY);
|
||||
ogs_sbi_server_send_error(stream,
|
||||
OGS_SBI_HTTP_STATUS_BAD_REQUEST, NULL,
|
||||
"Too many query parameters", NULL, NULL);
|
||||
|
||||
ogs_free(query);
|
||||
|
||||
ogs_free(namestr);
|
||||
ogs_free(valuestr);
|
||||
|
||||
return NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE;
|
||||
}
|
||||
|
||||
if (strlen(params[j].key))
|
||||
ogs_sbi_header_set(request->http.params,
|
||||
params[j].key, params[j].val);
|
||||
|
|
@ -1406,12 +1421,6 @@ static int on_header(nghttp2_session *session, const nghttp2_frame *frame,
|
|||
j++;
|
||||
}
|
||||
|
||||
if (j >= MAX_NUM_OF_PARAM_IN_QUERY+1) {
|
||||
ogs_fatal("Maximum number(%d) of query params reached",
|
||||
MAX_NUM_OF_PARAM_IN_QUERY);
|
||||
ogs_assert_if_reached();
|
||||
}
|
||||
|
||||
ogs_free(query);
|
||||
|
||||
} else if (namebuf.len == sizeof(METHOD) - 1 &&
|
||||
|
|
@ -1439,6 +1448,7 @@ static int on_data_chunk_recv(nghttp2_session *session, uint8_t flags,
|
|||
{
|
||||
ogs_sbi_stream_t *stream = NULL;
|
||||
ogs_sbi_request_t *request = NULL;
|
||||
char *content = NULL;
|
||||
|
||||
size_t offset = 0;
|
||||
|
||||
|
|
@ -1460,24 +1470,26 @@ static int on_data_chunk_recv(nghttp2_session *session, uint8_t flags,
|
|||
ogs_assert(request->http.content_length == 0);
|
||||
ogs_assert(offset == 0);
|
||||
|
||||
request->http.content = (char*)ogs_malloc(len + 1);
|
||||
content = (char*)ogs_malloc(len + 1);
|
||||
} else {
|
||||
ogs_assert(request->http.content_length != 0);
|
||||
|
||||
request->http.content = (char*)ogs_realloc(
|
||||
content = (char*)ogs_realloc(
|
||||
request->http.content, request->http.content_length + len + 1);
|
||||
}
|
||||
|
||||
if (!request->http.content) {
|
||||
if (!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;
|
||||
return NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE;
|
||||
}
|
||||
|
||||
request->http.content = content;
|
||||
|
||||
offset = request->http.content_length;
|
||||
request->http.content_length += len;
|
||||
|
||||
|
|
|
|||
|
|
@ -86,6 +86,19 @@ bool nrf_nnrf_handle_nf_register(ogs_sbi_nf_instance_t *nf_instance,
|
|||
return false;
|
||||
}
|
||||
|
||||
if (!NFProfile->fqdn &&
|
||||
(!NFProfile->ipv4_addresses || !NFProfile->ipv4_addresses->first) &&
|
||||
(!NFProfile->ipv6_addresses || !NFProfile->ipv6_addresses->first)) {
|
||||
ogs_error("NFProfile missing endpoint: id=%s type=%s",
|
||||
nf_instance->id,
|
||||
OpenAPI_nf_type_ToString(NFProfile->nf_type));
|
||||
ogs_assert(true ==
|
||||
ogs_sbi_server_send_error(
|
||||
stream, OGS_SBI_HTTP_STATUS_BAD_REQUEST,
|
||||
recvmsg, "NFProfile missing endpoint", nf_instance->id, NULL));
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Validate the PLMN-ID against configured serving PLMN-IDs */
|
||||
if (NFProfile->plmn_list) {
|
||||
/* Set PLMN status to invalid */
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue