Skip to content

arch/PowerPC: fix uninitialized read of insn->mnemonic in PPC_post_printer - #3005

Merged
Rot127 merged 2 commits into
capstone-engine:v5from
phix33:v5-ppc-postprinter-uninit-mnemonic
Jul 24, 2026
Merged

Rot127 merged 2 commits into
capstone-engine:v5from
phix33:v5-ppc-postprinter-uninit-mnemonic

Conversation

@phix33

@phix33 phix33 commented Jul 23, 2026 •

Copy link
Copy Markdown
Contributor

Your checklist for this pull request

  • I've documented or updated the documentation of every API function and struct this PR changes.
  • I've added tests that prove my fix is effective or that my feature works (if possible)

Detailed description

PPC_post_printer() derives update_cr0 and bh from insn->mnemonic, which is not filled at that point: fill_insn() in cs.c invokes the post printer before copying the mnemonic out of the printed buffer, so reading insn->mnemonic there is wrong by construction. It normally works only because PPC_printInst() copies the first output token into flat_insn->mnemonic — but five alias paths (mr, slwi/srwi, sldi, dcbt/dcbtst, dcbf) return early and skip that copy, so the post-printer reads memory the engine never wrote.

With cs_disasm_iter() (which reuses one cs_insn by design) the effect is deterministic: decoding add. then mr reports mr with update_cr0 = true; decoding bne+ then mr gives mr a branch hint. With cs_disasm() the result depends on heap contents (valgrind flags the read). Found via a randomly failing radare2 test; radare2 currently carries a workaround (radare2@2646d7712a).

Fix, in two parts:

  • PPC_post_printer() tests the last character of the mnemonic token of insn_asm (bounded by strcspn(insn_asm, " \t")), which always holds the current instruction's text. On PPC the record-form . and the branch hint +/- are always the final character of the mnemonic — verified across all 1666 asm strings in PPCGenAsmWriter.inc and every alias/hint printer (printAliasBcc, printPredicateOperand "pm", printATBitsAsHint all append the hint last). This also retires the old strstr(insn_asm, ".+") guard, which only ever defended against a + inside a PC-relative operand — out of reach once the check is confined to the mnemonic token.
  • fill_insn() now clears insn->mnemonic before invoking the post printer, with a comment stating the contract (post printers must parse insn_asm, not read insn->mnemonic), so no post printer can depend on stale contents again. No other arch's post printer reads insn->mnemonic/op_str (checked AArch64, ARM, X86, Sparc, SystemZ, TMS320C64x, XCore) — PPC was the only offender.

A fully structured derivation (no text parsing at all) was considered and deliberately not done here: update_cr0 from the register-write map (cs_reg_write(CR0) in PPC_get_insn_id) is not equivalent to the printed-dot semantics — FP record forms write CR1 (fadd.) and Altivec record forms write CR6 (vcmpequb.), so it would silently change the reported update_cr0 for those; and the branch hint is emitted by four independent printer mechanisms in v5, so there is no single place to set bh structurally. next is not affected either way (post_printer is NULL there and fill_insn() zeroes the mnemonic).

Test plan

tests/test_ppc_iter_detail.c (self-checking, runs under ctest; 7/16 checks fail before the fix, all pass after) plus three issues.cs entries pinning the preserved positives (add. sets Update-CR0, bne+/bne- report hints). Existing PPC issues.cs and suite/MC/PowerPC pass unchanged, and the full ctest suite (all arches) passes, confirming the fill_insn() change is a no-op everywhere else.

Closing issues

"None".

@github-actions github-actions Bot added the PowerPC Arch label Jul 23, 2026
…inter and add regression tests

Derive the update_cr0 and branch-hint checks from the last char of the
mnemonic token of insn_asm, which always holds the current instruction's
text; also clear insn->mnemonic in fill_insn() before the post printer
runs so no post printer can rely on stale contents again.
@phix33
phix33 force-pushed the v5-ppc-postprinter-uninit-mnemonic branch from 79fd0ce to 0448c31 Compare July 24, 2026 08:54
@github-actions github-actions Bot added the CS-core-files auto-sync label Jul 24, 2026

@Rot127 Rot127 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Thanks for the fix!
Please add the test to the CI and we are good to go.

Comment thread CMakeLists.txt

@Rot127 Rot127 Jul 24, 2026 •

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

in order to run this test you need to add a step in CITest.yaml.
Its a little more annoying than on the next branch because here it was never refactored.
Just adding a simple new step below the cstest one should be enough.

@github-actions github-actions Bot added the Github-files Github related files label Jul 24, 2026
@phix33

phix33 commented Jul 24, 2026

Copy link
Copy Markdown
Contributor Author

Added a CI step below cstest that runs the test in all three Linux jobs"

@Rot127
Rot127 merged commit 49e5aef into capstone-engine:v5 Jul 24, 2026
24 checks passed
@phix33
phix33 deleted the v5-ppc-postprinter-uninit-mnemonic branch August 12, 2026 21:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CS-core-files auto-sync Github-files Github related files PowerPC Arch

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants