| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
byte level
Reviewed every diff for memory-safety and object-lifetime changes -- added or removed bounds checks,
changed comparison constants, copy sizes, refcount and free/release restructuring, and validation on
host-facing entry points. Written up in fw/diffs/SECURITY-REVIEW.md.
One confirmed fix. HDCP 23.0.0.52 -> .57 changes hdcp2_rx_LC_Send_L_prime, the HDCP 2.x locality
check, from memcmp_be to ct_memcmp when verifying L'. memcmp_be returns as soon as a word differs;
ct_memcmp ORs every byte difference into an accumulator with no early exit. L' verification is
exactly where an early return leaks a byte-at-a-time timing oracle. receiver_id_lookup still uses
memcmp_be, which is correct since receiver IDs are not secret.
One fleet-wide change I cannot resolve. A call to SYS_DRV service 0x208 was added on error paths in
exactly the four content-protection TAs -- GCP 22.0.0.62, HDCP 23.0.0.59, MERIT 24.0.0.56, OPM
25.0.0.62 -- and in none of the other twelve modules. The shape is consistent, including a magic
0xF000 argument and, in ASD's inline equivalent, a 16-bit truncation guard before logging. It is a
coordinated error-reporting rollout; whether it also tears down protection state needs the SYS_DRV
image, which is not in this corpus. Flagged, not claimed.
One defect never fixed. asd_srm_header_check bounds the HDCP1 SRM length to 43..5120 but applies
only a lower bound to the HDCP2 length, never comparing it against the transport length. Identical
in all 18 ASD builds including the reference, so no fix ever shipped across the whole available
version range. This is the most actionable item and it is a negative diff result.
Eleven apparent fixes were refuted by reading the bytes, and the reasons generalise. Hex-Rays elides
dead stores but cannot elide a call, so 24 HDCP wrappers that already initialised their whole frame
inline appear to gain zero-initialisation when they merely switched to bzero_core. IDA mis-read one
build's tail call as a thunk and dropped 39 lines of merit_cmd03, inventing three bounds checks in a
function whose 208 bytes differ in four relocation bytes. And several checks were rewritten with
identical semantics: x >> 30 != 0 against x >= 0x40000000, x > 0x1F against x >= 0x20, len >= 0x2024
against len > 0x2023. CSU's minimum length rising from 0x14 to 0x24 accommodates a newly added
command, not an existing overflow -- cmd01 touches only 0x10..0x13.
Scope stated in the review: 2,944 functions change at byte level after filtering relocations, mostly
display and link programming. ASD's largest changes sit on FUZZY-tier cross-version pairings where
the identity is itself a similarity judgement, so no bound change is claimed on those, and
asd_dispatch's real 778 -> 1352 byte growth inside branch 33.0.0 is not fully attributed.
|
|
|
fw/ta_diff_all.py writes every meaningful same-branch consecutive-build diff to fw/diffs/, one file
per pair plus an INDEX.md.
Two correctness rules are baked in, both learned by getting them wrong first. The third version field
is a BRANCH, not a sequence -- ASD ships 33.0.0.x through 33.0.28.x in parallel -- so only same-branch
pairs are emitted; comparing across them made asd_dispatch oscillate 842/1306/1352 bytes, which is
branch identity misread as change over time. And the four noise sources measured earlier are
normalised away: tier annotations, address-derived tokens, long hex literals, local renumbering.
Each file leads with the size table from the index sidecars, which is the signal no decompiler
instability can fake: same function, different byte size means the code changed. Body hunks follow,
grouped per function, with local declarations dropped.
INDEX.md opens with four findings rather than making the reader hunt: the HDCP 23.0.0.52 -> .57
timing side-channel fix in the HDCP 2.x locality check, where L' verification moved from early-exit
memcmp_be to constant-time ct_memcmp; GCP's ASIC allowlist in cmdFE08 growing from 14 to 28 entries
across nine builds with 0xe backfilled out of order; the teardown sequence added to GCP's three
session-lifecycle handlers at 22.0.0.62; and a warning not to read ASD's dispatch case lists as
change, since the 48 labels that appear and vanish are Hex-Rays alternating between a switch and the
range check rpc_id - 384 <= 0x40.
The index marks `resized` as the trustworthy column and `new`/`gone` as leads, because a function
named in one build and not another shows up there without any firmware change behind it.
|