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]

@nathaniel-bennett nathaniel-bennett force-pushed the master branch 3 times, most recently from 60f5567 to 0831cdb Compare April 1, 2024 17:26
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 73f51d6.

♻️ This comment has been updated with latest results.

Copy link
Contributor

github-actions bot commented Apr 4, 2024

DP Lint & Test

0 tests   0 ✔️  0s ⏱️
0 suites  0 💤
0 files    0

Results for commit 73f51d6.

♻️ 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

@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

@nathaniel-bennett
Copy link
Author

I think I've figured out the issue--we'll see if CI accepts it now...

@nathaniel-bennett nathaniel-bennett force-pushed the master branch 2 times, most recently from 55a7105 to 484e841 Compare June 12, 2024 19:36
@lucasgonze
Copy link
Contributor

Yogesh will review and hopefully merge.

@nathaniel-bennett
Copy link
Author

I'll fix the lint errors and force-push again

@nathaniel-bennett nathaniel-bennett force-pushed the master branch 2 times, most recently from d140ee3 to 1d08857 Compare June 17, 2024 16:25
nathaniel-bennett referenced this pull request Jun 28, 2024
Signed-off-by: Nathaniel <me@nathanielbennett.com>
@nathaniel-bennett nathaniel-bennett force-pushed the master branch 2 times, most recently from f726c2e to c6a1b61 Compare July 8, 2024 16:42
@nathaniel-bennett
Copy link
Author

@lucasgonze There was one more lint error I somehow missed--I've fixed it and re-pushed.

@lucasgonze lucasgonze removed the request for review from brunohcfaria July 10, 2024 20:47
@lucasgonze
Copy link
Contributor

Removed Bruno Faria from approvers list.

@nathaniel-bennett
Copy link
Author

Looks like this passed all checks and just needs one more re-approval to be merged

@brunohcfaria
Copy link
Collaborator

@lucasgonze @jordanvrtanoski
I've reviewed the PR and it's good to go.
The checks are stalled after the latest rebase from master. Force pushing may trigger them to run again.

@jordanvrtanoski jordanvrtanoski enabled auto-merge (squash) August 9, 2024 14:35
@jordanvrtanoski jordanvrtanoski self-requested a review August 9, 2024 14:36
@nathaniel-bennett
Copy link
Author

Not sure why this is now failing CI... anyone able to force-push and trigger a rerun without removing the approved reviews? (once CI is fixed, that is)

Signed-off-by: Nathaniel <me@nathanielbennett.com>
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.

7 participants