simplify_primitive_compare_c at simplify_c.c:718 called hir_c_compare_op
on a HirPrimitiveCompare instr. hir_c_compare_op casts to HirCompare*
(HIR_DEOPT_FIELDS layout, op at offset ~104). HirPrimitiveCompare uses
HIR_INSTR_FIELDS (op at offset ~40, total slab ~48 bytes). Read at
instr+104 was ~56 bytes past the slab end, into adjacent (often freed)
memory.
Fix: add hir_c_primitive_compare_op accessor with correct
HirPrimitiveCompare* cast. Replace simplify_c.c:718 call.
Hardening (per pythia
python#161 python#4 + feedback_class_of_bug_audit.md):
add static_assert(offsetof(HirCompare, op) != offsetof(HirPrimitiveCompare, op))
in hir_instr_c_verify.cpp to prevent future single-accessor confusion.
Verification (testkeeper valgrind, post-fix):
Pre-fix: ERROR SUMMARY: 26 errors from 4 contexts
Post-fix: ERROR SUMMARY: 1 errors from 1 contexts
24 simplify_primitive_compare_c UAF errors ELIMINATED.
Re-verified post-amendment (generalist):
Post-amend: ERROR SUMMARY: 1 errors from 1 contexts (unchanged)
The remaining 1 error is the runtime StoreAttr NULL+0xAB deref
(W-PYTORCH-CM-(ii)) — a separate, independent bug per SoK 4-class
enumeration in docs/w-pytorch-cm-tooling-note.md.
Class-of-bug audit (per feedback_class_of_bug_audit.md):
- hir_c_compare_op (DEOPT cast): 4 callers — 3 correct (HirCompare
context at simplify_c.c:648 simplify_compare_c, dynamic_comparison_
elimination.c:102 guarded by hir_c_is_compare, pass_output_type_c.c:45
HIR_OP_Compare case), 1 BUGGY (simplify_c.c:718, fixed)
- hir_c_unary_op_kind (DEOPT cast): 3 callers, all correct
- hir_c_inplace_op_kind (DEOPT cast): 1 caller, correct
- hir_c_primitive_unary_op_kind (INSTR cast): exists, used correctly
- HirFloatCompare/HirLongCompare/HirUnicodeCompare/HirCompareBool:
no current op-field readers — would be candidates if added
Sole bug. No parallel type-confusion in current code.
Cinderx duplicate (per pythia
python#161 python#3): NON-ISSUE. Python/cinderx/Jit/hir/*
and Python/jit/hir/* are HARDLINKS (same inode); single edit covers both
include paths. Build resolves 'cinderx/Jit/hir/' include to
Python/cinderx/Jit/hir/, which is the same on-disk file as Python/jit/hir/.
F7 R1 'ASAN false positive' classification (D-1777177190) was incorrect.
ASAN/valgrind were right; this is a real type-confusion UAF that
manifested as garbage reads driving wrong simplification logic.
Bug latent because read past slab end returns garbage but doesn't
crash; PrimitiveCompare branches on garbage land in valid-looking code
most of the time. bench_pytorch_cm trigger correlates with workload
exercising PrimitiveCompare simplification heavily (autocast/_NoGrad
context manager enter/exit branches compile to PrimitiveCompare ops).
Build: scripts/build_phoenix.sh
Binary: /data/users/alexturner/phoenix/cpython/python
Binary timestamp: 1777204101 (Apr 26 04:48:21 PDT)
Binary md5: 687c34ef755aa6df9a2a57d7b568edc8
Backport of #160