mirror of
https://github.com/open5gs/open5gs.git
synced 2026-04-28 03:19:31 +00:00
proto: Prevent SMF crash on malformed PCO/EPCO during parsing
ogs_pco_parse() previously relied on ogs_assert() to verify the bounds of Protocol/Container fields while parsing PCO/EPCO data. If the outer PCO/EPCO length was inconsistent with the internal container encoding (e.g., truncated Container-ID, Container-Length, or container data), the assert would trigger and terminate the process. Because PCO/EPCO is derived from UE-supplied NAS messages (e.g., PDU Session Establishment Request), a malformed EPCO IE could trigger a remote SMF crash, resulting in a denial-of-service condition. This patch replaces the assert-based bounds checks with explicit runtime validation and returns an error when malformed or truncated PCO/EPCO is detected. The SMF can then reject the request cleanly instead of aborting. Checks added: - Validate minimum PCO/EPCO length before accessing header fields - Verify Container-ID bounds - Verify Container-Length bounds - Verify container payload length - Detect container count overflow beyond OGS_MAX_NUM_OF_PROTOCOL_OR_CONTAINER_ID With these changes, malformed EPCO inputs are safely rejected and the SMF remains operational. Issues: #4341
This commit is contained in:
parent
42506202e8
commit
6a29f11115
1 changed files with 31 additions and 2 deletions
|
|
@ -447,26 +447,55 @@ int ogs_pco_parse(ogs_pco_t *pco, unsigned char *data, int data_len)
|
|||
|
||||
memset(pco, 0, sizeof(ogs_pco_t));
|
||||
|
||||
if (data_len < 1) {
|
||||
ogs_error("PCO/EPCO too short [%d]", data_len);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
pco->ext = source->ext;
|
||||
pco->configuration_protocol = source->configuration_protocol;
|
||||
size++;
|
||||
|
||||
while(size < data_len && i < OGS_MAX_NUM_OF_PROTOCOL_OR_CONTAINER_ID) {
|
||||
ogs_pco_id_t *id = &pco->ids[i];
|
||||
ogs_assert(size + sizeof(id->id) <= data_len);
|
||||
|
||||
if (size + (int)sizeof(id->id) > data_len) {
|
||||
ogs_error("PCO/EPCO truncated before Container-ID "
|
||||
"[offset:%d len:%d]", size, data_len);
|
||||
return -EINVAL;
|
||||
}
|
||||
memcpy(&id->id, data + size, sizeof(id->id));
|
||||
id->id = be16toh(id->id);
|
||||
size += sizeof(id->id);
|
||||
|
||||
ogs_assert(size + sizeof(id->len) <= data_len);
|
||||
if (size + (int)sizeof(id->len) > data_len) {
|
||||
ogs_error("PCO/EPCO truncated before Container-Length "
|
||||
"[id:0x%x offset:%d len:%d]",
|
||||
id->id, size, data_len);
|
||||
return -EINVAL;
|
||||
}
|
||||
memcpy(&id->len, data + size, sizeof(id->len));
|
||||
size += sizeof(id->len);
|
||||
|
||||
if (size + id->len > data_len) {
|
||||
ogs_error("PCO/EPCO truncated Container data "
|
||||
"[id:0x%x container-len:%u offset:%d len:%d]",
|
||||
id->id, id->len, size, data_len);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
id->data = data + size;
|
||||
size += id->len;
|
||||
|
||||
i++;
|
||||
}
|
||||
|
||||
if (size < data_len) {
|
||||
ogs_error("PCO/EPCO exceeds maximum number of containers "
|
||||
"[%d]", OGS_MAX_NUM_OF_PROTOCOL_OR_CONTAINER_ID);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
pco->num_of_id = i;
|
||||
ogs_expect(size == data_len);
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue