Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(mme): Enforce stricter input validation for S1AP/NGAP/NAS payloads #15401

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

nathaniel-bennett
Copy link

Summary

The following patch resolves several reachable assertions, overflows, null-dereference and type confusion vulnerabilities present in S1AP, NGAP and NAS protocol handlers. The fixes themselves are generally one-liners that add an additional trivial check to ensure an index isn't out of bounds, or a mandatory IE isn't missing, or a reachable assertion is turned into a soft error.

Test Plan

Tested via fuzzing to ensure robustness.

Security Considerations

The following fix mitigates several vulnerabilities accessible by either malicious base station or unauthenticated UE.

@nathaniel-bennett nathaniel-bennett requested a review from a team as a code owner April 1, 2024 16:47
@pull-request-size pull-request-size bot added the size/L Denotes a Pull Request that changes 100-499 lines. label Apr 1, 2024
Copy link
Contributor

github-actions bot commented Apr 1, 2024

Thanks for opening a PR! 💯

A couple initial guidelines

Howto

  • Reviews. The "Reviewers" listed for this PR are the Magma maintainers who will shepherd it.
  • Checks. All required CI checks must pass before merge.
  • Merge. Once approved and passing CI checks, use the ready2merge label to indicate the maintainers can merge your PR.

More info

Please take a moment to read through the Magma project's

If this is your first Magma PR, also consider reading

@github-actions github-actions bot added the component: agw Access gateway-related issue label Apr 1, 2024
Copy link
Contributor

github-actions bot commented Apr 1, 2024

✔️ The Semantic PR check ended with status success. See instructions on formatting your commit and pull request titles.

@@ -564,6 +564,7 @@ int decode_emergency_number_list_ie(
buffer + decoded, EMERGENCY_NUMBER_MAX_DIGITS, len - decoded);

e->lengthofemergencynumberinformation = *(buffer + decoded);
CHECK_LENGTH_DECODER(((int) len) - decoded, e->lengthofemergencynumberinformation);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[cpplint] reported by reviewdog 🐶
Using C-style cast. Use static_cast(...) instead [readability/casting] [4]

@@ -577,7 +578,9 @@
i < EMERGENCY_NUMBER_MAX_DIGITS; i++) {
e->number_digit[i] = 0xFF;
}
Fatal("TODO emergency_number_list_t->next");

// TODO implement emergency_number_list_t->next
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[cpplint] reported by reviewdog 🐶
Missing username in TODO; it should look like "// TODO(my_username): Stuff." [readability/todo] [2]

@@ -590,7 +593,9 @@
uint32_t encoded = 0;
emergency_number_list_t* e = emergencynumberlist;

Fatal("TODO Implement encode_emergency_number_list_ie");
// TODO implement encode_emergency_number_list_ie
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[cpplint] reported by reviewdog 🐶
Missing username in TODO; it should look like "// TODO(my_username): Stuff." [readability/todo] [2]

@@ -73,7 +73,7 @@ int decode_access_point_name_ie(access_point_name_t* access_point_name,

ielen = *(buffer + decoded);
decoded++;
CHECK_LENGTH_DECODER(len - decoded, ielen);
CHECK_LENGTH_DECODER(((int) len) - decoded, ielen);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[cpplint] reported by reviewdog 🐶
Using C-style cast. Use static_cast(...) instead [readability/casting] [4]

@@ -236,6 +237,9 @@
protocolconfigurationoptions->num_protocol_or_container_id = 0;

while (3 <= ((int32_t)len - (int32_t)decoded)) {
if (protocolconfigurationoptions->num_protocol_or_container_id >= PCO_UNSPEC_MAXIMUM_PROTOCOL_ID_OR_CONTAINER_ID) {
return TLV_UNEXPECTED_IEI; // Maximum 30 options
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[cpplint] reported by reviewdog 🐶
At least two spaces is best between code and comments [whitespace/comments] [2]

@@ -803,7 +815,7 @@
}
}

if (len - decoded < 0) {
if (((int)len) - decoded < 0) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[cpplint] reported by reviewdog 🐶
Using C-style cast. Use static_cast(...) instead [readability/casting] [4]

@@ -46,7 +46,7 @@ int decode_esm_message_container(EsmMessageContainer* esmmessagecontainer,
}

DECODE_LENGTH_U16(buffer + decoded, ielen, decoded);
CHECK_LENGTH_DECODER(len - decoded, ielen);
CHECK_LENGTH_DECODER(((int) len) - decoded, ielen);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[cpplint] reported by reviewdog 🐶
Using C-style cast. Use static_cast(...) instead [readability/casting] [4]

if (iei > 0) {
CHECK_LENGTH_DECODER(((int) len) - decoded, 1);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[cpplint] reported by reviewdog 🐶
Using C-style cast. Use static_cast(...) instead [readability/casting] [4]

CHECK_IEI_DECODER(iei, *buffer);
decoded++;
}

CHECK_LENGTH_DECODER(((int) len) - decoded, 2);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[cpplint] reported by reviewdog 🐶
Using C-style cast. Use static_cast(...) instead [readability/casting] [4]

ielen = *(buffer + decoded);
decoded++;
CHECK_LENGTH_DECODER(len - decoded, ielen);
CHECK_LENGTH_DECODER(((int) len) - decoded, ielen);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[cpplint] reported by reviewdog 🐶
Using C-style cast. Use static_cast(...) instead [readability/casting] [4]

Copy link
Contributor

@panyogesh panyogesh left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

Copy link
Contributor

github-actions bot commented Apr 4, 2024

Oops! Looks like you failed the PR Check DCO. Be sure to sign all your commits.

Howto

♻️ Updated: ✅ The check is passing the PR Check DCO after the last commit.

Copy link
Contributor

github-actions bot commented Apr 4, 2024

FeG Lint & Test

    2 files  203 suites   39s ⏱️
374 tests 374 ✔️ 0 💤 0
388 runs  388 ✔️ 0 💤 0

Results for commit 4e9c20f.

♻️ This comment has been updated with latest results.

Copy link
Contributor

github-actions bot commented Apr 4, 2024

DP Lint & Test

14 tests   14 ✔️  2m 13s ⏱️
  1 suites    0 💤
  1 files      0

Results for commit 4e9c20f.

♻️ This comment has been updated with latest results.

@panyogesh
Copy link
Contributor

@nathaniel-bennett : Please fix the DCO check : PR Check DCO / DCO Check (pull_request) .
Details are there in the link https://github.com/magma/magma/actions/runs/8511282479/job/23422184541?pr=15401

@rdefosse
Copy link
Contributor

rdefosse commented Apr 4, 2024

@panyogesh @nathaniel-bennett

for me there is a build issue.

See https://jenkins-oai.eurecom.fr/view/MAGMA/job/MAGMA-MME-production/22103/artifact/magma_logs.zip

@mehul-jindal
Copy link
Contributor

Hi @nathaniel-bennett after the recent commit I'm observing just the one TC failure, could you work it out with the help of the logs attached?

//lte/gateway/c/core/oai/test/mme_app_task:mme_app_esm_encode_decode_test FAILED in 1.6s
=================================================================================
test.log
=================================================================================
exec ${PAGER:-/usr/bin/less} "$0" || exit 1
Executing tests from //lte/gateway/c/core/oai/test/mme_app_task:mme_app_esm_encode_decode_test
-----------------------------------------------------------------------------
Running main() from gmock_main.cc
[==========] Running 22 tests from 1 test suite.
[----------] Global test environment set-up.
[----------] 22 tests from ESMEncodeDecodeTest
[ RUN      ] ESMEncodeDecodeTest.TestActivateDefaultEpsBearerContextRequest
lte/gateway/c/core/oai/test/mme_app_task/test_mme_app_esm_encode_decode.cpp:255: Failure
Expected: (decoded) >= (0), actual: -9 vs 0
lte/gateway/c/core/oai/test/mme_app_task/test_mme_app_esm_encode_decode.cpp:256: Failure
Expected equality of these values:
  encoded
    Which is: 121
  decoded
    Which is: -9
lte/gateway/c/core/oai/test/mme_app_task/test_mme_app_esm_encode_decode.cpp:258: Failure
Expected equality of these values:
  original_msg->pdnaddress.pdntypevalue
    Which is: '\x3' (3)
  decoded_msg->pdnaddress.pdntypevalue
    Which is: '\0'
lte/gateway/c/core/oai/test/mme_app_task/test_mme_app_esm_encode_decode.cpp:262: Failure
Expected equality of these values:
  std::string((const char*)original_msg->accesspointname->data)
    Which is: "magma.ipv4"
  std::string((const char*)decoded_msg->accesspointname->data)
    Which is: "magma."

@nathaniel-bennett
Copy link
Author

Alright, I've figured it out--I refactored the equality symbol of an assertion the wrong way. The corrected code no longer returns -9 (TLV_OCTET_STRING_TOO_LONG_FOR_IEI) unless the ielen is less than the length_apn, not more.

        if (ielen < length_apn) {
          // Mismatch in lengths remaining between IE length and APN length
          return TLV_OCTET_STRING_TOO_LONG_FOR_IEI;
        }

@mehul-jindal
Copy link
Contributor

Hi @nathaniel-bennett, all required CI jobs except the one my screenshot refers to seem to be passing, to fix this, please commit using the --signoff flag, for instance:

git commit --signoff -s -m "fix(mme): Enforce stricter input validation for S1AP/NGAP/NAS payloads"

Please include the changes from my commit if you intend to push 'em in one go.
TIA!
image

Signed-off-by: Nathaniel <me@nathanielbennett.com>
@lucasgonze
Copy link
Contributor

The merge was blocked on a review from @pshelar, who is not responsive. I removed him from the reviewers list.

@rdefosse
Copy link
Contributor

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
component: agw Access gateway-related issue size/L Denotes a Pull Request that changes 100-499 lines.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants