This is a short post about another bug I discovered mostly by accident. While reversing libxpc, I
noticed that XPC string deserialization does not check whether the deserialized string is actually
as long as the serialized length claims: it could be shorter. That is, the serialized XPC message
might claim that the string is 1000 bytes long even though the string contains a null byte at
index 100. The resulting
OS_xpc_string object will then think its C string on the heap is longer
than it actually is.
While directly exploitating this vulnerability to execute arbitrary code is difficult, there’s
another path we can take. The length field of an
OS_xpc_string object is trusted when serializing
the string into a message, so if we can get an XPC service to send us back the string it just
deserialized, it will over-read from the heap C-string buffer and send us all of that extra data in
the message, giving us a snapshot of that process’s heap memory. The resulting exploit primitive is
similar to how the Heartbleed vulnerability could be used to over-read heap data from an
OpenSSL-powered server’s memory.