Skip to content

Return InvalidInstructionData for malformed token metadata instructions#1194

Open
bit2swaz wants to merge 2 commits into
solana-program:mainfrom
bit2swaz:fix/token-metadata-borsh-length-panic
Open

Return InvalidInstructionData for malformed token metadata instructions#1194
bit2swaz wants to merge 2 commits into
solana-program:mainfrom
bit2swaz:fix/token-metadata-borsh-length-panic

Conversation

@bit2swaz
Copy link
Copy Markdown
Contributor

@bit2swaz bit2swaz commented May 22, 2026

Closes #1152

Summary

Malformed token metadata payloads for Initialize, UpdateField, and RemoveKey could reach TokenMetadataInstruction::unpack(input), trigger Borsh allocation on forged string lengths, and abort the program as ProgramFailedToComplete. This adds a narrow pre-validation guard in program/src/processor.rs so recognized malformed payloads fail with InvalidInstructionData instead.

What changed

  • Added a local token-metadata pre-validation guard in program/src/processor.rs before TokenMetadataInstruction::unpack(input).
  • Matched only the affected metadata discriminators: Initialize, UpdateField, and RemoveKey.
  • Validated the affected payload layouts with slice/cursor walking and fixed-size reads.
  • Returned ProgramError::InvalidInstructionData for malformed recognized payloads instead of falling through or panicking.
  • Added regression tests for forged string-length prefixes in initialize, update-field, and remove-key flows.

Why

Before this change, malformed token metadata payloads for the affected variants could reach generic Borsh deserialization, attempt oversized allocation, and panic on SBF. In program-test this surfaced as ProgramFailedToComplete.

After this change, recognized malformed payloads are rejected locally and return InstructionError(0, InvalidInstructionData).

Scope

This change is intentionally narrow.

  • Only Initialize, UpdateField, and RemoveKey are pre-validated.
  • UpdateAuthority, Emit, and other metadata variants continue through the existing TokenMetadataInstruction::unpack(input) path unchanged.
  • The production change is local to program/src/processor.rs, with targeted regression coverage in the three Rust legacy metadata test files.

Tests

  • Added fail_initialize_with_forged_name_length_returns_invalid_instruction_data.
  • Added fail_update_field_with_forged_value_length_returns_invalid_instruction_data.
  • Added fail_remove_key_with_forged_key_length_returns_invalid_instruction_data.
  • Ran nearby success coverage:
    • success_initialize
    • success_update
    • success_remove

Notes

The Rust legacy integration tests load target/deploy/spl_token_2022.so via program-test, so rebuild the SBF artifact with make build-sbf-program before running make test-clients-rust-legacy

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.

spl-token-2022 token-metadata decoder panics on forged Borsh string lengths

1 participant