Kernel plist integer parsing silently saturates decimal values exceeding INT64_MAX (unsigned fallback is dead code)
Summary
When kernel internalizes attacker-supplied XML plist <integer> with decimal value in range (INT64_MAX UINT64_MAX] value silently corrupted to INT64_MAX. ERANGE overflow check in _prop_number_internalize_signed guarded by #ifndef _KERNEL (kernel has no errno) so strtoq silent saturation (strtoq.c:122-123 returns QUAD_MAX on overflow no externally visible indication) goes undetected function always returns true. Short-circuit && at line 584 ensures _prop_number_internalize_unsigned never called making entire try-signed fall-back-to-unsigned design non-functional in kernel. Userland build unaffected checks errno==ERANGE. Decimal value > 9223372036854775807 stored as signed INT64_MAX instead of correct unsigned value. pnv_is_unsigned flag set incorrectly (false instead of true). Hex path (0x prefix) correctly routes to strtouq handles full uint64_t range so only DECIMAL unsigned values > INT64_MAX affected. Any local user submitting plist to kernel ioctl (prop_dictionary_copyin_ioctl) can trigger. Kernel silently stores wrong value and wrong signedness flag. Data-integrity violation on attacker-controlled input. Kernel/userland desynchronization in proplib-using protocols.
No comments yet.