
Android 14 Kernel-Exploit für Pixel7/8 Pro
Dieser Artikel bietet eine detaillierte Analyse von zwei Kernel-Schwachstellen im Mali GPU, die aus der standardmäßigen Anwendungs-Sandbox erreichbar sind, welche ich unabhängig identifiziert und Google gemeldet habe. Er enthält einen Kernel-Exploit, der beliebige Kernel-Lese-/Schreibfunktionen erreicht. Dadurch wird SELinux deaktiviert und root-Berechtigungen auf Google Pixel 7 und 8 Pro Modellen mit den folgenden Android 14 Versionen erlangt:
google/husky/husky:14/UD1A.231105.004/11010374:user/release-keysgoogle/cheetah/cheetah:14/UP1A.231105.003/11010452:user/release-keysgoogle/cheetah/cheetah:14/UP1A.231005.007/10754064:user/release-keysgoogle/panther/panther:14/UP1A.231105.003/11010452:user/release-keys (von m4b4 (Marcel))Dieser Exploit nutzt zwei Schwachstellen aus: einen Integer-Überlauf, der aus einem unvollständigen Patch im gpu_pixel_handle_buffer_liveness_update_ioctl ioctl-Befehl resultiert, und einen Informationsleck innerhalb der Timeline-Stream-Message-Puffer.
Google behob einen Integer-Überlauf im gpu_pixel_handle_buffer_liveness_update_ioctl ioctl-Befehl in diesem Commit. Anfangs, als ich dieses Problem meldete, nahm ich an, dass der Fehler durch eine Problem im oben beschriebenen Patch verursacht wurde. Nach Durchsicht des Berichts erkannte ich, dass meine Analyse der Schwachstelle ungenau war. Trotz meiner ersten Annahme, dass der Patch unvollständig sei, beseitigt und verhindert er effektiv einen Underflow in der Berechnung. Dies ließ mich vermuten, dass die Änderung nicht in den Produktionsversionen angewendet wurde. Obwohl ich jedoch einen Underflow in der Berechnung verursachen kann, ist es nicht möglich, einen Überlauf zu verursachen. Dies deutet darauf hin, dass der ioctl-Befehl teilweise gefixt wurde, jedoch nicht mit dem oben gezeigten Patch. Ein Blick in IDA ergab, dass ein weiterer unvollständiger Patch in den Produktionsversionen ausgeliefert wurde, und dieser Patch ist in keinem Git-Zweig des Mali GPU-Kernelmoduls vorhanden.
Diese Schwachstelle wurde erstmals in der neuesten Android-Version entdeckt und am 19. November 2023 gemeldet. Google teilte mir später mit, dass sie sie bereits intern identifiziert und ihr CVE-2023-48409 im Android-Sicherheitsbulletin vom Dezember zugewiesen hatten, und stufte sie als Duplikat ein. Obwohl ich bestätigen konnte, dass der Fehler Monate vor meiner Meldung intern identifiziert worden war (basierend auf dem Commit-Datum um den 30. August), bleibt Verwirrung. Insbesondere ist es seltsam, dass die Security Patch Levels (SPL) für Oktober und November der neuesten Geräte noch von dieser Schwachstelle betroffen waren – ich habe keine Versionen vor diesen untersucht. Daher kann ich nicht abschließend feststellen, ob es sich tatsächlich um ein Duplikat handelte und ob der entsprechende Patch vor meiner Einreichung bereits für Dezember eingeplant war oder ob es ein Versehen bei der Behebung dieser Schwachstelle gab.
Jedenfalls macht Folgendes diesen Bug mächtig:
info.live_ranges ist vollständig benutzerkontrolliert.info.live_ranges an einem beliebigen Offset vor dem Start der Kerneladresse buff liegen kann.Diese Schwachstelle weist Ähnlichkeiten mit der DeCxt::RasterizeScaleBiasData() Buffer Underflow-Schwachstelle auf, die ich im iOS 15 Kernel im Jahr 2022 gefunden und ausgenutzt habe.
Die GPU Mali implementiert einen benutzerdefinierten Timeline Stream, der Informationen sammelt, serialisiert und anschließend in einem bestimmten Format in einen Ringpuffer schreibt. Benutzer können den ioctl-Befehl kbase_api_tlstream_acquire aufrufen, um einen Dateideskriptor zu erhalten, der es ihnen ermöglicht, aus diesem Ringpuffer zu lesen. Das Format der Nachrichten ist wie folgt:
Ein Paket-Header
Eine Nachrichten-ID
Ein serialisierter Nachrichtenpuffer, dessen spezifischer Inhalt von der Nachrichten-ID abhängt.
Beispielsweise serialisiert die Funktion __kbase_tlstream_tl_kbase_kcpuqueue_enqueue_fence_wait die Kernel-Pointer kbase_kcpu_command_queue und dma_fence in den Nachrichtenpuffer, was zu einem Leck von Kernel-Pointern an den Userspace-Prozess führt.```c
void __kbase_tlstream_tl_kbase_kcpuqueue_enqueue_fence_wait(
struct kbase_tlstream *stream,
const void *kcpu_queue,
const void *fence
)
{
const u32 msg_id = KBASE_TL_KBASE_KCPUQUEUE_ENQUEUE_FENCE_WAIT;
const size_t msg_size = sizeof(msg_id) + sizeof(u64)
+ sizeof(kcpu_queue)
+ sizeof(fence)
;
char *buffer;
unsigned long acq_flags;
size_t pos = 0;
buffer = kbase_tlstream_msgbuf_acquire(stream, msg_size, &acq_flags);
pos = kbasep_serialize_bytes(buffer, pos, &msg_id, sizeof(msg_id)); pos = kbasep_serialize_timestamp(buffer, pos); pos = kbasep_serialize_bytes(buffer, pos, &kcpu_queue, sizeof(kcpu_queue)); pos = kbasep_serialize_bytes(buffer, pos, &fence, sizeof(fence));
kbase_tlstream_msgbuf_release(stream, acq_flags); }
Der Proof-of-Concept-Exploit leak die Adresse des `kbase_kcpu_command_queue`-Objekts, indem er die Nachrichten-ID `KBASE_TL_KBASE_NEW_KCPUQUEUE` überwacht, die von der Funktion `kbasep_kcpu_queue_new` ausgelöst wird, wenn ein neues KCPU-Warteschlangenobjekt zugewiesen wird.
Google informierte mich, dass die Schwachstelle im März 2023 gemeldet und im Sicherheitsbulletin mit [CVE-2023-26083](https://source.android.com/docs/security/bulletin/2023-07-01) versehen wurde. Dennoch konnte ich das Problem auf den neuesten Pixel-Geräten mit den Sicherheitspatch-Stufen (SPL) für Oktober und November reproduzieren, was darauf hindeutet, dass der Fix nicht korrekt oder überhaupt nicht angewendet wurde. Anschließend hat Google das Problem im Dezember-Sicherheitsupdate-Bulletin schnell behoben, ohne Anerkennung zu geben, und mich später informiert, dass das Problem als Duplikat betrachtet wurde. Die Begründung für die Einstufung als Duplikat bleibt jedoch fragwürdig.
## Ausnutzung
---
Also habe ich zwei interessante Schwachstellen. Die erste bietet eine leistungsstarke Fähigkeit, den Inhalt einer beliebigen, 16-Byte-alignierten Kernel-Adresse zu modifizieren, die vor der allokierten ~buff~-Adresse liegt. Die zweite Schwachstelle liefert Hinweise auf die möglichen Positionen von Objekten im Kernel-Speicher.