nfapi: fix integer overflows in SRS report handling for large arrays

With 64 gNB antenna elements the SRS channel IQ matrix exceeds the
ranges the SRS report code path was written for (272 PRGs * 2 UE ports
* 64 elements * 4 B = 136 KiB per report):

- unpack_nr_srs_report_tlv_value(): last_idx was int16_t, which
  overflows at report lengths >= 128 KiB, so the copy loop never ran
  and the report was silently dropped. Widen to int32_t and reject
  reports larger than the value buffer instead of overrunning it.
- pack/unpack_nr_srs_normalized_channel_iq_matrix():
  channel_matrix_size was uint16_t and wraps at 64 KiB, truncating the
  matrix. Widen to uint32_t and bound it by sizeof(channel_matrix).
- handle_nr_srs_measurements(): the SRS_IND_DEBUG print indexed the
  matrix with a uint16_t, which wraps for Nu*Ng*Np > 65535.

Assisted-by: Claude Code:claude-fable-5
Signed-off-by: default avatarGabriele Gemmi <g.gemmi@northeastern.edu>
parent 7aff1cd2
...@@ -2405,6 +2405,14 @@ uint8_t pack_nr_srs_indication(void *msg, uint8_t **ppWritePackedMsg, uint8_t *e ...@@ -2405,6 +2405,14 @@ uint8_t pack_nr_srs_indication(void *msg, uint8_t **ppWritePackedMsg, uint8_t *e
uint8_t unpack_nr_srs_report_tlv_value(nfapi_srs_report_tlv_t *report_tlv, uint8_t **ppReadPackedMsg, uint8_t *end) uint8_t unpack_nr_srs_report_tlv_value(nfapi_srs_report_tlv_t *report_tlv, uint8_t **ppReadPackedMsg, uint8_t *end)
{ {
if ((report_tlv->length + 3) / 4 > sizeof(report_tlv->value) / sizeof(report_tlv->value[0])) {
NFAPI_TRACE(NFAPI_TRACE_ERROR,
"%s: SRS report TLV too large to unpack (length %u bytes, max %zu), dropping report\n",
__FUNCTION__,
report_tlv->length,
sizeof(report_tlv->value));
return 0;
}
#ifndef ENABLE_AERIAL #ifndef ENABLE_AERIAL
for (int i = 0; i < (report_tlv->length + 3) / 4; i++) { for (int i = 0; i < (report_tlv->length + 3) / 4; i++) {
if (!pull32(ppReadPackedMsg, &report_tlv->value[i], end)) { if (!pull32(ppReadPackedMsg, &report_tlv->value[i], end)) {
...@@ -2412,7 +2420,7 @@ uint8_t unpack_nr_srs_report_tlv_value(nfapi_srs_report_tlv_t *report_tlv, uint8 ...@@ -2412,7 +2420,7 @@ uint8_t unpack_nr_srs_report_tlv_value(nfapi_srs_report_tlv_t *report_tlv, uint8
} }
} }
#else #else
const int16_t last_idx = ((report_tlv->length + 3) / 4) - 1; const int32_t last_idx = ((report_tlv->length + 3) / 4) - 1;
for (int i = 0; i < last_idx; i++) { for (int i = 0; i < last_idx; i++) {
if (!pull32(ppReadPackedMsg, &report_tlv->value[i], end)) { if (!pull32(ppReadPackedMsg, &report_tlv->value[i], end)) {
return 0; return 0;
......
...@@ -147,7 +147,7 @@ int pack_nr_srs_normalized_channel_iq_matrix(void *pMessageBuf, void *pPackedBuf ...@@ -147,7 +147,7 @@ int pack_nr_srs_normalized_channel_iq_matrix(void *pMessageBuf, void *pPackedBuf
return 0; return 0;
} }
uint16_t channel_matrix_size = nr_srs_normalized_channel_iq_matrix->num_prgs uint32_t channel_matrix_size = (uint32_t)nr_srs_normalized_channel_iq_matrix->num_prgs
* nr_srs_normalized_channel_iq_matrix->num_ue_srs_ports * nr_srs_normalized_channel_iq_matrix->num_ue_srs_ports
* nr_srs_normalized_channel_iq_matrix->num_gnb_antenna_elements; * nr_srs_normalized_channel_iq_matrix->num_gnb_antenna_elements;
if (nr_srs_normalized_channel_iq_matrix->normalized_iq_representation == 0) { if (nr_srs_normalized_channel_iq_matrix->normalized_iq_representation == 0) {
...@@ -157,8 +157,11 @@ int pack_nr_srs_normalized_channel_iq_matrix(void *pMessageBuf, void *pPackedBuf ...@@ -157,8 +157,11 @@ int pack_nr_srs_normalized_channel_iq_matrix(void *pMessageBuf, void *pPackedBuf
// 1: 32-bit normalized complex number (iqSize = 4) // 1: 32-bit normalized complex number (iqSize = 4)
channel_matrix_size <<= 2; channel_matrix_size <<= 2;
} }
if (channel_matrix_size > sizeof(nr_srs_normalized_channel_iq_matrix->channel_matrix)) {
return 0;
}
for (int i = 0; i < channel_matrix_size; i++) { for (uint32_t i = 0; i < channel_matrix_size; i++) {
if (!push8(nr_srs_normalized_channel_iq_matrix->channel_matrix[i], &pWritePackedMessage, end)) { if (!push8(nr_srs_normalized_channel_iq_matrix->channel_matrix[i], &pWritePackedMessage, end)) {
return 0; return 0;
} }
...@@ -409,7 +412,7 @@ int unpack_nr_srs_normalized_channel_iq_matrix(void *pMessageBuf, ...@@ -409,7 +412,7 @@ int unpack_nr_srs_normalized_channel_iq_matrix(void *pMessageBuf,
return -1; return -1;
} }
uint16_t channel_matrix_size = nr_srs_normalized_channel_iq_matrix->num_prgs uint32_t channel_matrix_size = (uint32_t)nr_srs_normalized_channel_iq_matrix->num_prgs
* nr_srs_normalized_channel_iq_matrix->num_ue_srs_ports * nr_srs_normalized_channel_iq_matrix->num_ue_srs_ports
* nr_srs_normalized_channel_iq_matrix->num_gnb_antenna_elements; * nr_srs_normalized_channel_iq_matrix->num_gnb_antenna_elements;
if (nr_srs_normalized_channel_iq_matrix->normalized_iq_representation == 0) { if (nr_srs_normalized_channel_iq_matrix->normalized_iq_representation == 0) {
...@@ -419,8 +422,11 @@ int unpack_nr_srs_normalized_channel_iq_matrix(void *pMessageBuf, ...@@ -419,8 +422,11 @@ int unpack_nr_srs_normalized_channel_iq_matrix(void *pMessageBuf,
// 1: 32-bit normalized complex number (iqSize = 4) // 1: 32-bit normalized complex number (iqSize = 4)
channel_matrix_size <<= 2; channel_matrix_size <<= 2;
} }
if (channel_matrix_size > sizeof(nr_srs_normalized_channel_iq_matrix->channel_matrix)) {
return -1;
}
for (int i = 0; i < channel_matrix_size; i++) { for (uint32_t i = 0; i < channel_matrix_size; i++) {
if (!pull8(&pReadPackedMessage, &nr_srs_normalized_channel_iq_matrix->channel_matrix[i], end)) { if (!pull8(&pReadPackedMessage, &nr_srs_normalized_channel_iq_matrix->channel_matrix[i], end)) {
return 0; return 0;
} }
......
...@@ -1563,7 +1563,7 @@ void handle_nr_srs_measurements(const module_id_t module_id, ...@@ -1563,7 +1563,7 @@ void handle_nr_srs_measurements(const module_id_t module_id,
for (int uI = 0; uI < nr_srs_channel_iq_matrix.num_ue_srs_ports; uI++) { for (int uI = 0; uI < nr_srs_channel_iq_matrix.num_ue_srs_ports; uI++) {
for (int gI = 0; gI < nr_srs_channel_iq_matrix.num_gnb_antenna_elements; gI++) { for (int gI = 0; gI < nr_srs_channel_iq_matrix.num_gnb_antenna_elements; gI++) {
for (int pI = 0; pI < nr_srs_channel_iq_matrix.num_prgs; pI++) { for (int pI = 0; pI < nr_srs_channel_iq_matrix.num_prgs; pI++) {
uint16_t index = uI * nr_srs_channel_iq_matrix.num_gnb_antenna_elements * nr_srs_channel_iq_matrix.num_prgs + gI * nr_srs_channel_iq_matrix.num_prgs + pI; uint32_t index = (uint32_t)uI * nr_srs_channel_iq_matrix.num_gnb_antenna_elements * nr_srs_channel_iq_matrix.num_prgs + gI * nr_srs_channel_iq_matrix.num_prgs + pI;
LOG_I(NR_MAC, LOG_I(NR_MAC,
"(uI %i, gI %i, pI %i) channel_matrix --> real %i, imag %i\n", "(uI %i, gI %i, pI %i) channel_matrix --> real %i, imag %i\n",
uI, uI,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment