Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

CVE-2026-28825: smbfs, macOS 26.3.1 to 26.4

This repeats the patch diff in MAD Bugs: An Apple Kernel Bug, Brought to You by Microsoft. smb2_rq_decompress_read copied compress_len bytes of a compressed SMB 2 reply without comparing it with the buffer it had allocated. The fix adds that comparison, with an error path that logs compress_len %u > originalCompressedSegmentSize %u.

The report diffs 26.3.2. The IPSW feed holds no 26.3.2 for the VirtualMac2,1, so this compares 26.3.1, which has the bug too, and more changes besides.

Get the binaries

$ ipsw download ipsw --macos --device VirtualMac2,1 --build 25D2128 --kernel --output 26.3.1
$ ipsw download ipsw --macos --device VirtualMac2,1 --build 25E246 --kernel --output 26.4
$ ipsw kernel extract 26.3.1/*/kernelcache.release.VirtualMac2,1 com.apple.filesystems.smbfs --output 26.3.1
$ ipsw kernel extract 26.4/*/kernelcache.release.VirtualMac2,1 com.apple.filesystems.smbfs --output 26.4

Compare

$ hereticus --format markdown 26.3.1/com.apple.filesystems.smbfs 26.4/com.apple.filesystems.smbfs
FUNCTIONCHANGESCORE+/-/~TOUCHEDMATCHED BY
_smb_iod_threadchanged0.89285/386/15444 branch, 50 call, 24 jump, 151 mem, 41 const, 15 textsame name
…
_smb2_rq_decompress_readchanged0.9781/68/316 branch, 16 call, 2 jump, 35 mem, 31 const, 2 textsame name
…

762 matched (194 unchanged, 568 changed), 1 gone, 3 new

110 changed only a constant, hidden. Use –show-retouched to list them.

The fix is row 9 of 568: the kext changed a great deal over these two releases.

Read the fix

$ hereticus --diff _smb2_rq_decompress_read 26.3.1/com.apple.filesystems.smbfs 26.4/com.apple.filesystems.smbfs
...
+ sub w9, w8, #0x10
+ str w9, [sp, #0x44]
+ ldr w8, [sp, #0x4c]
+ str w8, [sp, #0x3c]
+ cmp w9, w8
+ b.hi $+0x24c
+ mov w2, w9
  add x0, sp, #0x80
  mov x1, x20
  mov w3, #0x0
  bl $+0x13164
...

cmp w9, w8 with b.hi is the new check the report names: compress_len against OriginalCompressedSegmentSize, before the copy.