[SEC] Heap overflow in open5gs-mmed/s1ap (#3153)

Assert shall be triggered if the mme_enb_t object is corrupted.

```
$ gdb -q -p `pidof open5gs-mmed`
..
Using host libthread_db library "/lib/aarch64-linux-gnu/libthread_db.so.1".
0x0000ffff90deb46c in __GI___sigtimedwait (set=set@entry=0xfffffe63be68, info=info@entry=0xfffffe63bda8, timeout=timeout@entry=0x0) at ../sysdeps/unix/sysv/linux/sigtimedwait.c:61
61      ../sysdeps/unix/sysv/linux/sigtimedwait.c: No such file or directory.
Breakpoint 1 at 0xaaaabef69250: file ../src/mme/s1ap-handler.c, line 199.
[Switching to Thread 0xffff1efdef00 (LWP 20348)]

Thread 38 "open5gs-mmed" hit Breakpoint 1, s1ap_handle_s1_setup_request (enb=0xffff9029b5a0, message=0xffff1efdc498) at ../src/mme/s1ap-handler.c:199
warning: Source file is more recent than executable.
199         if (maximum_number_of_enbs_is_reached()) {
(gdb) p enb.supported_ta_list
$1 = {{plmn_id = {mcc1 = 0 '\000', mcc2 = 0 '\000', mcc3 = 1 '\001', mnc1 = 15 '\017', mnc2 = 0 '\000', mnc3 = 1 '\001'}, tac = 1} <repeats 256 times>}
(gdb) p enb
$2 = (mme_enb_t *) 0xffff9029b5a0
(gdb) p *enb
$3 = {lnode = {prev = 0x0, next = 0x0}, sm = {init = 0xaaaabef66540 <s1ap_state_initial>, fini = 0xaaaabef66640 <s1ap_state_final>, state = 0xaaaabef66730 <s1ap_state_operational>}, enb_id = 1, plmn_id = {
    mcc1 = 1 '\001', mcc2 = 2 '\002', mcc3 = 3 '\003', mnc1 = 15 '\017', mnc2 = 4 '\004', mnc3 = 5 '\005'}, sctp = {type = 1, sock = 0xfffedc000bd0, addr = 0xfffedc000e70, poll = {read = 0xffff9032a0f0,
      write = 0x0}, write_queue = {prev = 0x0, next = 0x0}}, state = {s1_setup_success = false}, max_num_of_ostreams = 30, ostream_id = 0, num_of_supported_ta_list = 258, supported_ta_list = {{plmn_id = {
        mcc1 = 0 '\000', mcc2 = 0 '\000', mcc3 = 1 '\001', mnc1 = 15 '\017', mnc2 = 0 '\000', mnc3 = 1 '\001'}, tac = 1} <repeats 256 times>}, s1_reset_ack = 0x10f100000110f100, enb_ue_list = {prev = 0x1,
    next = 0x0}}
pwndbg> vmmap enb
LEGEND: STACK | HEAP | CODE | DATA | RWX | RODATA
             Start                End Perm     Size Offset File
    0xffff8edd4000     0xffff8ede4000 ---p    10000      0 [anon_ffff8edd4]
►   0xffff8ede4000     0xffff90650000 rw-p  186c000      0 [anon_ffff8ede4] +0x1517010
    0xffff90650000     0xffff90659000 r-xp     9000      0 /usr/lib/aarch64-linux-gnu/libffi.so.8.1.0
```

The value s1_reset_ack = 0x10f100000110f100 shall contain a function pointer, but has been corrupted.

The following patch will abort the process:

```diff
$ diff --git a/src/mme/s1ap-handler.c b/src/mme/s1ap-handler.c
index dff401ded..55a1f7e1b 100644
--- a/src/mme/s1ap-handler.c
+++ b/src/mme/s1ap-handler.c
@@ -178,6 +178,7 @@ void s1ap_handle_s1_setup_request(mme_enb_t *enb, ogs_s1ap_message_t *message)
                 SupportedTAs_Item->broadcastPLMNs.list.array[j];
             ogs_assert(pLMNidentity);

+           ogs_assert(enb->num_of_supported_ta_list < OGS_ARRAY_SIZE(enb->supported_ta_list));
             memcpy(&enb->supported_ta_list[enb->num_of_supported_ta_list].tac,
                     tAC->buf, sizeof(uint16_t));
             enb->supported_ta_list[enb->num_of_supported_ta_list].tac =
@@ -310,6 +311,7 @@ void s1ap_handle_enb_configuration_update(
                     SupportedTAs_Item->broadcastPLMNs.list.array[j];
                 ogs_assert(pLMNidentity);

+               ogs_assert(enb->num_of_supported_ta_list < OGS_ARRAY_SIZE(enb->supported_ta_list));
                 memcpy(&enb->supported_ta_list[
                         enb->num_of_supported_ta_list].tac,
                         tAC->buf, sizeof(uint16_t));
```
This commit is contained in:
Sukchan Lee
2024-05-01 16:23:13 +09:00
parent 7ea82cb87b
commit b57722178a
3 changed files with 91 additions and 1 deletions

View File

@@ -4,7 +4,7 @@ on: [push, pull_request]
jobs:
macos-latest:
name: Build and Test on MacOS Latest
runs-on: macos-latest
# runs-on: macos-latest
steps:
# - name: Install MongoDB with Package Manager
# run: |

View File

@@ -209,6 +209,16 @@ void ngap_handle_ng_setup_request(amf_gnb_t *gnb, ogs_ngap_message_t *message)
i++) {
NGAP_SupportedTAItem_t *SupportedTAItem = NULL;
if (gnb->num_of_supported_ta_list >=
OGS_ARRAY_SIZE(gnb->supported_ta_list)) {
ogs_error("OVERFLOW GNB->num_of_supported_ta_list "
"[%d:%d:%d]",
gnb->num_of_supported_ta_list,
OGS_MAX_NUM_OF_SUPPORTED_TA,
(int)OGS_ARRAY_SIZE(gnb->supported_ta_list));
break;
}
SupportedTAItem = (NGAP_SupportedTAItem_t *)
SupportedTAList->list.array[i];
if (!SupportedTAItem) {
@@ -235,6 +245,17 @@ void ngap_handle_ng_setup_request(amf_gnb_t *gnb, ogs_ngap_message_t *message)
NGAP_BroadcastPLMNItem_t *BroadcastPLMNItem = NULL;
NGAP_PLMNIdentity_t *pLMNIdentity = NULL;
if (gnb->supported_ta_list[i].num_of_bplmn_list >=
OGS_ARRAY_SIZE(gnb->supported_ta_list[i].bplmn_list)) {
ogs_error("OVERFLOW GNB->supported_ta_list.num_of_bplmn_list "
"[%d:%d:%d]",
gnb->supported_ta_list[i].num_of_bplmn_list,
OGS_MAX_NUM_OF_BPLMN,
(int)OGS_ARRAY_SIZE(
gnb->supported_ta_list[i].bplmn_list));
break;
}
BroadcastPLMNItem = (NGAP_BroadcastPLMNItem_t *)
SupportedTAItem->broadcastPLMNList.list.array[j];
if (!BroadcastPLMNItem) {
@@ -268,6 +289,19 @@ void ngap_handle_ng_setup_request(amf_gnb_t *gnb, ogs_ngap_message_t *message)
NGAP_SliceSupportItem_t *SliceSupportItem = NULL;
NGAP_S_NSSAI_t *s_NSSAI = NULL;
if (gnb->supported_ta_list[i].bplmn_list[j].num_of_s_nssai >=
OGS_ARRAY_SIZE(
gnb->supported_ta_list[i].bplmn_list[j].s_nssai)) {
ogs_error("OVERFLOW GNB->supported_ta_list."
"bplmn_list.num_of_s_nssai [%d:%d:%d]",
gnb->supported_ta_list[i].bplmn_list[j].
num_of_s_nssai,
OGS_MAX_NUM_OF_SLICE_SUPPORT,
(int)OGS_ARRAY_SIZE(gnb->
supported_ta_list[i].bplmn_list[j].s_nssai));
break;
}
SliceSupportItem = (NGAP_SliceSupportItem_t *)
BroadcastPLMNItem->tAISliceSupportList.list.array[k];
if (!SliceSupportItem) {
@@ -4272,6 +4306,16 @@ void ngap_handle_ran_configuration_update(
i++) {
NGAP_SupportedTAItem_t *SupportedTAItem = NULL;
if (gnb->num_of_supported_ta_list >=
OGS_ARRAY_SIZE(gnb->supported_ta_list)) {
ogs_error("OVERFLOW GNB->num_of_supported_ta_list "
"[%d:%d:%d]",
gnb->num_of_supported_ta_list,
OGS_MAX_NUM_OF_SUPPORTED_TA,
(int)OGS_ARRAY_SIZE(gnb->supported_ta_list));
break;
}
SupportedTAItem = (NGAP_SupportedTAItem_t *)
SupportedTAList->list.array[i];
if (!SupportedTAItem) {
@@ -4299,6 +4343,17 @@ void ngap_handle_ran_configuration_update(
NGAP_BroadcastPLMNItem_t *BroadcastPLMNItem = NULL;
NGAP_PLMNIdentity_t *pLMNIdentity = NULL;
if (gnb->supported_ta_list[i].num_of_bplmn_list >=
OGS_ARRAY_SIZE(gnb->supported_ta_list[i].bplmn_list)) {
ogs_error("OVERFLOW GNB->supported_ta_list."
"num_of_bplm_list [%d:%d:%d]",
gnb->supported_ta_list[i].num_of_bplmn_list,
OGS_MAX_NUM_OF_BPLMN,
(int)OGS_ARRAY_SIZE(
gnb->supported_ta_list[i].bplmn_list));
break;
}
BroadcastPLMNItem = (NGAP_BroadcastPLMNItem_t *)
SupportedTAItem->broadcastPLMNList.list.array[j];
if (!BroadcastPLMNItem) {
@@ -4333,6 +4388,21 @@ void ngap_handle_ran_configuration_update(
NGAP_SliceSupportItem_t *SliceSupportItem = NULL;
NGAP_S_NSSAI_t *s_NSSAI = NULL;
if (gnb->supported_ta_list[i].
bplmn_list[j].num_of_s_nssai >=
OGS_ARRAY_SIZE(gnb->supported_ta_list[i].
bplmn_list[j].s_nssai)) {
ogs_error("OVERFLOW GNB->num_of_supported_ta_list."
"bplmn_list.num_of_s_nssai"
"[%d:%d:%d]",
gnb->supported_ta_list[i].bplmn_list[j].
num_of_s_nssai,
OGS_MAX_NUM_OF_SLICE_SUPPORT,
(int)OGS_ARRAY_SIZE(gnb->supported_ta_list[i].
bplmn_list[j].s_nssai));
break;
}
SliceSupportItem = (NGAP_SliceSupportItem_t *)
BroadcastPLMNItem->tAISliceSupportList.list.array[k];
if (!SliceSupportItem) {

View File

@@ -178,6 +178,16 @@ void s1ap_handle_s1_setup_request(mme_enb_t *enb, ogs_s1ap_message_t *message)
SupportedTAs_Item->broadcastPLMNs.list.array[j];
ogs_assert(pLMNidentity);
if (enb->num_of_supported_ta_list >=
OGS_ARRAY_SIZE(enb->supported_ta_list)) {
ogs_error("OVERFLOW ENB->num_of_supported_ta_list "
"[%d:%d:%d]",
enb->num_of_supported_ta_list,
OGS_MAX_NUM_OF_SUPPORTED_TA,
(int)OGS_ARRAY_SIZE(enb->supported_ta_list));
break;
}
memcpy(&enb->supported_ta_list[enb->num_of_supported_ta_list].tac,
tAC->buf, sizeof(uint16_t));
enb->supported_ta_list[enb->num_of_supported_ta_list].tac =
@@ -310,6 +320,16 @@ void s1ap_handle_enb_configuration_update(
SupportedTAs_Item->broadcastPLMNs.list.array[j];
ogs_assert(pLMNidentity);
if (enb->num_of_supported_ta_list >=
OGS_ARRAY_SIZE(enb->supported_ta_list)) {
ogs_error("OVERFLOW ENB->num_of_supported_ta_list "
"[%d:%d:%d]",
enb->num_of_supported_ta_list,
OGS_MAX_NUM_OF_SUPPORTED_TA,
(int)OGS_ARRAY_SIZE(enb->supported_ta_list));
break;
}
memcpy(&enb->supported_ta_list[
enb->num_of_supported_ta_list].tac,
tAC->buf, sizeof(uint16_t));