Moderne Linux-Systeme bieten mit der Schnittstelle io_uring eine besonders effiziente Methode für Ein- und Ausgaben. Zugleich ist sie eine potenzielle Schwachstelle, denn viele Sicherheitslösungen, die nur klassische Systemaufrufe überwachen, könnten Angriffe über io_uring nicht bemerken.
Ein Forschungsteam hat eine Sicherheitslücke in gängigen Sicherheitswerkzeugen für Linux aufgedeckt. Sie beruht auf der Art und Weise, wie moderne Linux-Systeme Ein- und Ausgabevorgänge mithilfe der io_uring-Schnittstelle verarbeiten. Die Technologie wurde im Jahr 2019 mit Version 5.1 des Linux-Kernels eingeführt und soll die Leistung von I/O-intensiven Anwendungen wie Datenbanken, Webservern oder Netzwerkdiensten verbessern.
Vor allem bei Anwendungen, die viele kleine Lese- oder Schreiboperationen initiieren, kann sie die Performance im Vergleich zu herkömmlichen Mechanismen deutlich steigern. In traditionellen I/O-Modellen führen solche Vorgänge oft zu Blockaden. Dann muss ein Programm erst auf die Antwort des Kernels warten, bevor es weiterarbeiten kann.
io_uring hingegen erlaubt es, zahlreiche Anfragen gleichzeitig zu stellen, die der Kernel im Hintergrund verarbeitet, während das Programm weiterläuft. Die Technik vermeidet im Interesse einer höheren Effizienz explizite Syscalls für I/O-Operationen. Darin liegt allerdings eine Herausforderung für viele Sicherheitssysteme. Sie verlassen sich auf die Überwachung dieser Schnittstelle zwischen einem Benutzerprogramm und dem Kernel.
Ein Anwendungsprogramm kann nicht direkt auf Hardware oder Kernel-Funktionen zugreifen, sondern muss dafür bestimmte, definierte Funktionen aufrufen – beispielsweise um Dateien zu öffnen, Daten zu lesen oder Netzwerkpakete zu senden. Die Funktionen wie »read()«, »write()«, »open()« oder »execve()« lösen im Hintergrund sogenannte Syscalls aus. Der Kernel nimmt die Anfragen entgegen, prüft ihre Berechtigung, führt sie aus und gibt das Ergebnis zurück.
Vor allem Tools zur Erkennung von Rootkits basieren auf dem Monitoring von Syscalls. Hinter Rootkits stecken spezielle Programme oder Module, die darauf ausgelegt sind, sich selbst und schädliche Aktivitäten zu verbergen. Sie greifen tief in das Betriebssystem ein, um ihre Spuren zu verwischen. Typischerweise tauschen sie zentrale Systemfunktionen aus oder manipulieren Datenstrukturen, sodass etwa Prozesse, Dateien oder Netzwerkverbindungen nicht mehr zu sehen sind – weder für den Benutzer noch für Sicherheitsprogramme. Als besonders gefährlich gelten Kernel-Rootkits, die häufig gewöhnliche Syscalls nutzen. Viele Sicherheitswerkzeuge beobachten genau diese Übergänge zwischen dem Benutzer- und dem Kernel-Bereich, um verdächtige oder unerlaubte Aktivitäten auszumachen.
Die io_uring-Schnittstelle unterläuft dieses Prinzip jedoch. Statt jeder einzelnen Aktion einen Syscall zuzuordnen, arbeitet io_uring mit einem anderen Mechanismus, dem Ringpuffer. Dabei handelt es sich um zwei spezielle Speicherbereiche: die Submission Queue für auszuführende Befehle und die Completion Queue für Rückmeldungen. Beide werden sowohl vom Benutzerprogramm als auch vom Kernel gemeinsam genutzt. Diese Puffer werden einmalig eingerichtet, meist über einen einzigen initialen Syscall wie »io_uring_setup()«.
Danach lassen sich viele I/O-Vorgänge direkt über die geteilten Speicherbereiche abwickeln. Dementsprechend braucht es nach der Einrichtung keine weiteren klassischen Syscalls mehr, um beispielsweise eine Datei zu lesen, Daten zu schreiben oder Netzwerkverbindungen zu bedienen. Das Programm legt Anfragen in den Ringpuffer, der Kernel holt sie daraufhin ab, verarbeitet sie und schiebt die Ergebnisse zurück in den Puffer. Das geschieht asynchron, weswegen das Programm nicht warten muss, bis die Vorgänge abgeschlossen sind.
Gerade dieses Umgehen der üblichen Systemaufrufe macht io_uring aus Sicht der IT-Sicherheit so problematisch, denn vollständig über io_uring abgewickelte Aktivitäten sind unsichtbar. Ein Schadprogramm, das sich dieses Verhalten zunutze macht, operiert somit unterhalb des Radars. Genau das demonstrierte das Forscherteam mit einem speziell entwickelten Proof-of-Concept-Rootkit namens Curing [1], das ausschließlich auf io_uring basiert.
Auch Lösungen wie Tetragon, die nicht nur Syscalls, sondern auch bestimmte Kernel-Ereignisse überwachen können, sind nicht automatisch gegen diese Art der Verschleierung geschützt. Sie erfordern, dass erfahrene Nutzer eigene Überwachungsrichtlinien für io_uring definieren – was allerdings fundiertes Wissen über die interne Funktionsweise dieser Schnittstelle voraussetzt.
Der Proof of Concept zeigt eindrücklich, wie tiefgreifend neue Betriebssystemfunktionen bestehende Sicherheitsmodelle beeinflussen können. Sie müssen sich kontinuierlich an technische Entwicklungen wie io_uring anpassen. Ansonsten riskieren sie, bestimmte Angriffsmethoden nicht mehr erkennen zu können. (jcb)
Infos
- Proof-of-Concept: https://github.com/armosec/curing





