CVE-2021-30883: AppleCLCD, iOS 15.0.1 to 15.0.2
This repeats the patch diff in
Saar Amar: Bindiff and POC for the IOMFB vulnerability.
IOMFB::TableCompensator::BilerpGainTable::new_from_data computed the size
of a table in 32 bits, as 12 * v15 * v14 + 4 * (v14 + a3), and allocated
that much. The fix computes it in 64 bits, puts upper limits on the counts,
and checks the allocation for NULL.
An iPhone 11 is used: the A14 and later run this code on the DCP instead.
Get the binaries
$ ipsw download ipsw --device iPhone12,1 --build 19A348 --kernel --output 15.0.1
$ ipsw download ipsw --device iPhone12,1 --build 19A404 --kernel --output 15.0.2
The kernelcache of iOS 15 on an A13 is no fileset, but one image with every kext linked in, so it is compared whole.
Compare
$ hereticus --format markdown 15.0.1/*/kernelcache.release.iPhone12,1 15.0.2/*/kernelcache.release.iPhone12,1
| FUNCTION | CHANGE | SCORE | +/-/~ | TOUCHED | MATCHED BY |
|---|---|---|---|---|---|
sub_fffffff009c0b13c -> sub_fffffff009c0b178 | changed | 0.72 | 28/16/5 | 3 branch, 4 call, 3 jump, 8 mem | similar |
sub_fffffff009c0a39c | changed | 0.40 | 10/14/2 | 1 branch, 2 call, 1 jump, 4 mem | same callers |
sub_fffffff009c0aedc -> sub_fffffff009c0aef8 | changed | 0.89 | 14/5/4 | 2 branch, 1 call, 1 mem | similar |
| … |
114843 matched (114507 unchanged, 336 changed), 1 gone, 2 new
6 changed only a constant, hidden. Use –show-retouched to list them.
The first row is the function from the report, out of 336 changed in the whole kernel. It adds the most instructions.
Read the fix
$ hereticus --diff sub_fffffff009c0b13c 15.0.1/*/kernelcache.release.iPhone12,1 15.0.2/*/kernelcache.release.iPhone12,1
...
- cmp w25, #0x0
- csinc w9, w25, wzr, ne
- mul w9, w8, w9
- mov w22, #0xc
- mul w9, w9, w22
- add w8, w8, w25
- add w0, w9, w8, lsl #2
bl $-0xdcc
+ cbz w0, $+0x54
...
ldr w8, [x19, #0x20]
+ cmp w8, #0x64
+ b.hi $+0x10
ldr w9, [x19, #0x10]
+ cmp w9, #0x3e9
+ b.lo $+0x70
...
The size 12 * v15 * v14 + 4 * (v14 + a3) in 32-bit registers is gone. A
call computes it now, a zero result leaves through the new error path, and
the two counts are limited to 100 and 1000: the upper limits the report
names.