Skip to content

[xabt] Validate CustomJniInitFunctions names are valid C identifiers#10935

Merged
jonathanpeppers merged 1 commit intomainfrom
dev/peppers/AndroidStaticJniInitFunction
Mar 13, 2026
Merged

[xabt] Validate CustomJniInitFunctions names are valid C identifiers#10935
jonathanpeppers merged 1 commit intomainfrom
dev/peppers/AndroidStaticJniInitFunction

Conversation

@jonathanpeppers
Copy link
Member

Reject AndroidStaticJniInitFunction items that are not valid C identifiers before they reach the LLVM IR generator. A malicious NuGet package could inject arbitrary LLVM IR directives via newlines or special characters in function names (CWE-74).

Reject AndroidStaticJniInitFunction items that are not valid C
identifiers before they reach the LLVM IR generator. A malicious
NuGet package could inject arbitrary LLVM IR directives via
newlines or special characters in function names (CWE-74).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings March 13, 2026 16:19
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR hardens the NativeAOT build pipeline by validating @(AndroidStaticJniInitFunction) (passed into CustomJniInitFunctions) so that only valid C identifiers are accepted, preventing potential LLVM IR injection via crafted item specs.

Changes:

  • Add C-identifier validation (and newline rejection) for CustomJniInitFunctions before generating LLVM IR.
  • Add a NativeAOT release build test ensuring invalid function names fail the build with an appropriate error.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.

File Description
src/Xamarin.Android.Build.Tasks/Tasks/GenerateNativeAotLibraryLoadAssemblerSources.cs Validates custom JNI init function names before feeding them into the LLVM IR generator.
src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/BuildTest2.cs Adds a regression test covering rejection of invalid custom JNI init function names.

Copy link
Member Author

@jonathanpeppers jonathanpeppers left a comment

Choose a reason for hiding this comment

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

🤖 AI Review Summary

Verdict: ✅ LGTM

Clean, well-targeted security fix (CWE-74 injection via LLVM IR) with a good regression test. No issues found.

👍 Positives:

  • Security: The ValidCIdentifier regex + IndexOfAny newline check provides defense-in-depth against LLVM IR injection. The newline check is technically redundant (the regex already rejects non-identifier characters), but making the injection vector explicit in the code is good security practice.
  • Fail fast: Throwing InvalidOperationException from RunTask() is the right call for a security validation — AndroidTask converts it to an error automatically, and there's zero chance of continuing with a tainted value.
  • Testing: The InvalidCustomJniInitFunctionName test exercises the full build pipeline end-to-end with both valid and invalid function names, properly uses IgnoreUnsupportedConfiguration, and asserts both build failure and error message content.
  • Error message: Includes the offending value ('{name}') — good context for debugging.

💡 Optional follow-up (not blocking): Consider adding a proper XA#### error code with Log.LogCodedError and a Properties.Resources entry in a future PR. This would give users a documented, searchable error code instead of the generic AndroidTask exception wrapper.


CI Status

Pipeline Status Notes
dotnet-android (Linux) ✅ Pass
dotnet-android (Mac) ✅ Pass
dotnet-android (Windows) ✅ Pass
license/cla ✅ Pass
Xamarin.Android-PR ❌ Fail Infrastructure flake — safe to ignore. The macOS > Tests > MSBuild+Emulator 6 job failed with: "We stopped hearing from agent Azure Pipelines 156." This is an agent connectivity loss, not a code failure. All other failures in that pipeline (APKs 1, Package Tests) are cascading from the lost agent.

Review generated by android-reviewer from review guidelines.

@jonathanpeppers jonathanpeppers merged commit 2f0f414 into main Mar 13, 2026
9 of 10 checks passed
@jonathanpeppers jonathanpeppers deleted the dev/peppers/AndroidStaticJniInitFunction branch March 13, 2026 20:44
@jonathanpeppers
Copy link
Member Author

Note that this is classified as a "reliability bug" not security.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants