Digital Eliteboard - Das Digitale Technik Forum

Registriere dich noch heute kostenloses um Mitglied zu werden! Sobald du angemeldet bist, kannst du auf unserer Seite aktiv teilnehmen, indem du deine eigenen Themen und Beiträge erstellst und dich über deinen eigenen Posteingang mit anderen Mitgliedern unterhalten kannst! Zudem bekommst du Zutritt zu Bereiche, welche für Gäste verwehrt bleiben

Hardware & Software Linux 5.14 mit "geheimem" Speicher und sicherem Hyperthreading

Nur wenige Tage nach dem 30. Jahrestag der allerersten Ankündigung von Linux hat Linus Torvalds die Kernel-Version 5.14 freigegeben. In der aktuellen Release-Meldung griff Torvalds diesen Zufall scherzhaft auf. Er verstehe, dass zum 30. Jahrestag sicherlich alle mit Galas und schicken Events beschäftigt seien, habe jedoch eine nette Abwechslung von Glitzer, Champagner und Co. parat: ein neues Kernel-Release zum Testen und Genießen.

Linux 5.14, das zwischen zwei symbolträchtige Jahrestage, nämlich die Linux-Ankündigung am 25. August 1991 und das allererste Kernel-Release am 17. September desselben Jahres fällt, ist im Vergleich zu einigen seiner Vorgänger der jüngeren Vergangenheit kein gigantisches Release. Auf den ersten Blick könnte es gar als bloßes "Standard-Update" mit neuen und verbesserten Treibern durchgehen. Allerdings verdienen einige weniger offensichtliche, aber durchaus signifikante Neuerungen etwas Aufmerksamkeit – darunter etwa die komplette Streichung des alten IDE-Treibersystems, sogenanntes "Core-Scheduling" als Abwehrmaßnahme gegen Spectre-Angriffsvarianten sowie geheime Speicherbereiche.

Altes IDE entfernt​

Der bisherige IDE-Treiber (Integrated Drive Electronics) galt bereits seit Linux 5.2 als veraltet (deprecated) und sollte mit einem der Kernel-Releases in 2021 aus Linux verschwinden. Linux 5.14 setzt dieses Vorhaben jetzt um: Der Treiber ist Geschichte.

Bereits die Ankündigung des Wegfalls hatte im Vorfeld für heiße Diskussionen gesorgt: Viele Nutzer sahen ihre alten, per Flachbandkabel angeschlossenen Festplatten und die darauf aufbauenden Systeme schon auf dem Wertstoffhof landen. Doch so schlimm kommt es nicht: Bei dem ausrangierten Treiber handelt es sich lediglich um den "Legacy-IDE-Treiber", der Datenträger via Parallel-ATA (PATA) beziehungsweise IDE anspricht und Laufwerke über Gerätenamen wie /dev/hda, /dev/hdb und Co. bereitstellt.

Was in den 1990ern und früher 2000ern fast ausschließlich genutzt wurde, spielt bei modernen Systemen keine Rolle mehr. Denn mit dem Aufkommen von Serial ATA (SATA) erhielt der Linux-Kernel einen neuen Treiber namens libata. Dieser stellt die neueren SATA-Geräte als /dev/sda, /dev/sdb etc. bereit. Zunächst gab es jeweils einen separaten Treiber für PATA (in Gestalt des Legacy-IDE-Treibers) und SATA (in Form von libata). Doch schon sehr bald legte libata nach, um auch PATA-Geräte ansteuern zu können.

Selbst alte Systeme mittlerweile umgestellt​

Die meisten Linux-Distributionen setzen schon seit Jahren auf libata und die Mainstream-Distributionen sind allesamt umgestellt. Zuletzt waren es lediglich alte Systeme mit Motorola MC680x0, die noch auf den Legacy-Treiber angewiesen waren. Mit dem
Du musst dich Anmelden oder Registrieren um diesen link zusehen!
war die Atari-Fraktion mit dem Falcon und modifizierten Mega STE und TT030 bereit für den Umstieg. Nach dem
Du musst dich Anmelden oder Registrieren um diesen link zusehen!
für einige klassische 68k-Macs wie den Quadra 630 war dann auch die letzte Hürde genommen. Das Entfernen des alten Legacy-ID-Treibers erleichterte den Linux-Kernel um über 41.000 Zeilen Code.

Core-Scheduling gegen Spectre​

Nach über drei Jahren Entwicklungszeit ist das sogenannte Core-Scheduling im Mainline-Kernel angekommen. Es adressiert ein konzeptionelles Problem des Hyperthreading moderner Prozessoren, das durch die 2018 entdeckten
Du musst dich Anmelden oder Registrieren um diesen link zusehen!
zutage trat.

Hyperthreading oder "Simultaneous Multithreading" (SMT) ermöglicht das Ausführen zweier oder mehr Threads auf einem Prozessorkern (Core). Der Core zeigt sich nach außen wie ein abgespeckter Mehrkernprozessor. "Abgespeckt" deshalb, da immer nur ein Thread aktiv sein kann und läuft – echte Parallelverarbeitung wie bei einem Multicore beherrscht Hyperthreading nicht. Und dennoch ist es sinnvoll, da Wartezeiten einzelner Threads von anderen Threads genutzt, "Leerläufe" reduziert und CPU-Ressourcen somit effizienter genutzt werden können.

Beim Hyperthreading nutzen die Hardware-Threads Komponenten des Prozessor-Cores gemeinsam – vor allem die Prozessor-Cache-Speicher. An dieser Stelle setzen Spectre und verwandte Angriffe an. Ein bösartiger Prozess auf einem Thread kann auf Änderungen in den Caches lauern. Zu diesen Änderungen können etwa Daten anderer Threads zählen, deren Prozesse sich auf diese Weise ausspähen lassen. Fährt ein System sehr unterschiedliche Lasten aus unterschiedlichen Quellen, wie beispielsweise ein Cloud-Provider, entsteht schnell eine Sicherheitsgrauzone. Der einzige wirklich sichere Ausweg war bislang, Hyperthreading zu deaktivieren.

Vertraust du mir, vertrau ich dir​

Core-Scheduling bietet für das Problem nun eine bessere Lösung. Es lässt nur Prozesse gemeinsam in Hardware-Threads eines Core laufen, die die gleiche Vertrauensstufe besitzen. Bezogen auf das Beispiel des Cloud-Providers werden Cluster von Kunden so aufgeteilt, dass sie sich keine Cores im Hyperthreading teilen: Prozesse eines Kunden laufen nur mit Prozessen desselben Kunden auf einem Core zusammen. Die Kunden können sich so gegenseitig nicht ausspionieren und Hyperthreading lässt sich dennoch nutzen.

Intern führt der Kernel hierzu "Cookies" ein. Diese Cookies weist das Core-Scheduling den Prozessen zu und markiert diese so als zueinander gehörig. Prozesse mit identischen Cookies dürfen auf denselben Cores im Hyperthreading laufen, "vertrauen" sich also. Aus den lauffähigen Prozessen, den verfügbaren Cores und deren Threads sowie den Cookie-Gruppen berechnet das Core-Scheduling dann passende Abläufe und die Verteilung der Prozesse auf die Cores/Threads.

Implementiert ist die API zum Core-Scheduling in der Sammlung verschiedenster Operationen für Prozesse und Threads von
Du musst dich Anmelden oder Registrieren um diesen link zusehen!
. Über die hinzugekommene Option PR_SCHED_CORE lassen sich Cookies erzeugen und diesen Prozessen zuweisen. Beim Erzeugen ist ein Prozess als "Blaupause" anzugeben. Dieser Prozess erhält den neuen Cookie. Das Zuweisen an andere Prozesse erfolgt dann über das "Auslesen" und Zuweisen desselben Cookies an einen anderen Prozess. Im Kernel sind derweil mehrere Sicherheitsmaßnahmen aktiv, damit sich kein Prozess einen Cookie erschleichen kann und Cookies stets eindeutig sind.

Kekssteuerung​

Während des Scheduling ändert sich mit dem neuen Feature initial nichts: Ein Prozessor wird unabhängig von Cookies mit dem höchst priorisierten Prozess aus der Run-Queue zum Ausführen bestückt. Bei aktivem Core-Scheduling sendet der Core danach jedoch ein Interprozesssignal an seine Thread-Ausführungseinheiten. Jede Thread-Einheit prüft daraufhin, ob der Cookie des eigenen Prozesses mit dem des soeben bestückten Prozesses des aktiven Threads übereinstimmt. Ist das der Fall, so behält der Thread seinen Prozess und wartet aufs Aktivieren. Stimmen die Cookies hingegen nicht überein, erfolgt ein Switch zu einem Prozess mit passendem Cookie. Ist kein Prozess mit passendem Cookie in der Run-Queue vorhanden, geht der Thread in den Wartezustand statt einen anderen, nicht vertrauenswürdigen Prozess auszuführen.

Dem Grundgedanken und der Effizienz des Hyperthreading läuft dieser Wechsel in den Wartemodus trotz lauffähiger Prozesse in der Run-Queue zuwider. Dennoch ist die Core-Auslastung dabei immer noch besser als bei einer kompletten Deaktivierung des Hyperthreading. Core-Scheduling ist somit ein guter Kompromiss zwischen optimierter Hardware-Auslastung und Sicherheitsanspruch.

Der Einsatz des Core-Scheduling kann nicht nur die Sicherheit erhöhen, sondern auch in anderen Bereichen nützlich sein – etwa bei Echtzeitsystemen, bei denen Hyperthreading typischerweise ausgeschaltet ist. Denn Echtzeitverarbeitung ist nur dann möglich, wenn ein Prozessorkern ausschließlich dem Echtzeitprozess zur Verfügung steht. Quer treibende Threads können dies unterlaufen. Mit Core-Scheduling können Echtzeitprozesse über dedizierte Cookies einzelnen Cores fix zugewiesen werden. Wenn es keine anderen Prozesse mit gleichen Cookies gibt, gehen die anderen Threads des jeweiligen Kerns dauerhaft in den Wartestatus. Jene Prozesse, die nicht in Echtzeit verarbeiten müssen, können sich Cookies und somit auch Cores im Hyperthreading teilen.

Streng geheimer Speicher​

Ein weiteres "Langzeit-Projekt", das jetzt nach rund zwei Jahren Entwicklungszeit und 23 Versionen im Mainline-Kernel angekommen ist, ist der neue, vorerst allerdings standardmäßig deaktivierte System-Call memfd_secret(). Userspace-Prozesse können mit ihm einen Speicherbereich schaffen, der durch keinen anderen Systemteil einsehbar ist – nicht einmal durch den Kernel selbst. Prädestiniert ist ein solcher Speicherbereich für das Ablegen von geheimen und besonders schützenswerten Informationen wie beispielsweise kryptographischen Schlüsseln oder Passwörtern. Selbst Angriffen auf die virtuelle Speicherverwaltung und auch Hardware-Bugs wie Spectre soll dieser Mechanismus widerstehen.

Nach einem Aufruf von memfd_secret() erhält der aufrufende Prozess einen File-Descriptor auf den neuen geheimen Speicher. Nach diesem ersten Registrieren des Speichers legt ein Aufruf von ftruncate() dessen Größe fest. Ein nachfolgendes Ausführen von mmap() spiegelt die "virtuelle" Datei schließlich in den Adressraum des aufrufenden Prozesses.

Der Kernel seinerseits entfernt den geheimen Speicher aus einer direkten Speicher-Map (direct map) und markiert diesen zusätzlich, um ihn vor irrtümlichem Wiederverwenden zu schützen. Mit diesen Aktionen verliert der Kernel den Zugriff auf den Speicher. Theoretisch könnte der Kernel den geheimen Speicher auch wieder in die "direct map" zurückholen. Dazu fehlt aber unter normalen Umständen eine entsprechende vorgefertigte Funktion.

Ein kompromittierter Kernel könnte dieses Zurückholen allerdings implementieren – etwa im Zuge eines Schadcode-Befalls, bei dem die im Kernel-Code bereits vorhandenen Anlagen um entsprechende Funktionen ergänzt werden. Hier wird deutlich: Das Konzept des geheimen Speichers, ein reiner Software-Mechanismus, funktioniert nur in einem vertrauenswürdigem Umfeld. Für mehr Schutz wären Hardware-Features notwendig, ähnlich denen, die
Du musst dich Anmelden oder Registrieren um diesen link zusehen!
nutzen. SEV und SGX sind auch auf einem kompromierten Hostsystem noch sicher; memfd_secret() hingegen nicht.

Konsequenzen von memfd_secret()​

Der geheime Speicherbereich ist, da der Kernel ihn nicht mehr "sieht", nicht in System-Calls einsetzbar. Ebenso können DMA-Operationen (Direct Memory Access) den Speicher nicht nutzen. Da sowohl System-Calls als auch DMA die geheimen Daten in den Kernel beziehungsweise in Kernel-sichtbaren Speicher tragen würden, was den Sinn eines "geheimen Speichers" allgemein in Frage stellen würde, sind diese Einschränkungen allerdings rein theoretischer Natur.

Ganz praktische Auswirkungen kann das Konzept auf lieb gewonnene Gewohnheiten haben. Um den geheimen Speicher vor allen ungewollten Blicken abzuschirmen, ist er auf physischen RAM beschränkt und soll nicht auf Festplatte ausgelagert werden können. Daher entschieden sich die Entwickler, den Ruhezustand ("Hibernate") des Systems bei aktivem memfd_secret() zu deaktivieren. Denn beim Hibernate schreibt das System seinen RAM-Inhalt temporär auf die Festplatte und schaltet sich aus. Bei aktivem memfd_secret() weiterhin nutzbar ist hingegen der Standby-Modus, bei dem die Speicherinhalte im (weiterhin mit Strom versorgten) RAM verbleiben.

memfd_secret() standardmäßig deaktiviert​

Trotz der Aufnahme in den Mainline-Kernel bringen die Kernel-Entwickler ihrer Schöpfung memfd_secret() kein blindes Vertrauen entgegen: memfd_secret() ist standardmäßig deaktiviert. Erst die Option secretmem_enable auf der Kernel-Kommandozeile macht den System-Call nutzbar. Das Entwickler-Team befürchtet, dass die Performance des Systems einbrechen könnte, wenn die "direct map" beschädigt werden könnte. Eingriffe ins Memory-Management sind grundsätzlich heikel, und selbst kleine Fehler können immense Auswirkungen haben. Daher ist es besser, das Feature nur dort gezielt zu aktivieren, wo es wirklich eingesetzt werden soll.

Zudem könnten die geheimen Speicherbereiche das verfügbare physische RAM verknappen. Im schlimmsten Fall, so die Befürchtung einiger Entwickler, könnte im RAM ein durch geheimen Speicher zerstückelter Flickenteppich entstehen. Im Extremfall könnte das System letztlich mehr mit Swapping als mit dem Erbringen seiner eigentlichen Aufgabe beschäftigt sein. Ob sich solche Befürchtungen bewahrheiten, müssen die Zeit und die gesammelten Erfahrungen mit Anwendungen zeigen, die das Feature in Zukunft nutzen werden.

ARM Pointer Authentication generalüberholt​

Der neue Kernel bringt seine Unterstützung für die sogenannte "ARM Pointer Authentication" auf den neuesten Stand. Das mit ARM 8.3 eingeführte Feature nutzt die freien Bits von 64-Bit-Zeigern der ARM64-Architektur, um die Zeiger kryptographisch zu signieren und so die Sicherheit zu verbessern. Vor einem Zugriff auf einen Zeiger prüft das System die Signatur; nur wer den passenden Schlüssel hat, kann gültige Zeiger erzeugen. Durch einen Buffer-Overflow überschriebene Pointer infolge eines Programmfehlers oder "umgebogene" Zeiger bei einem Angriff können keine korrekte Signatur aufweisen. Somit können Bugs und Angriffsversuche frühzeitig erkannt und abgewehrt werden.

Die ARM Pointer Authentication ist bereits seit Linux 4.21 Bestandteil des Kernels, beschränkte sich jedoch zunächst auf Prozesse im Userspace.
Du musst dich Anmelden oder Registrieren um diesen link zusehen!
. Bislang konnte man es nur wahlweise generell ein- oder ausschalten; mit Linux 5.14 lässt es sich nun
Du musst dich Anmelden oder Registrieren um diesen link zusehen!
.

Du musst dich Anmelden oder Registrieren um diesen link zusehen!
, die die "Enhanced PAC Generation Logic" umfasst. Das "Erraten" eines passenden Schlüssels ist damit noch schwerer als zuvor. Zudem ändert sich mit ARM8.3-FPAC die Fault-Logic beim Verarbeiten von ungültigen Signaturen. Diese Änderungen sind zum Erfüllen der ARM-8.3-Spezifikation zwar optional, allerdings unentbehrlich, um zukünftig ARM-8.6 zu erfüllen.

Virtualisierungs-News​

In der Virtualisierungs-Infrastruktur KVM (Kernel-based Virtual Machines) auf der ARM64-Architektur können mit Linux 5.14 nicht mehr nur Host-, sondern auch Gastsysteme die "Memory Tagging Extension" (MTE) nutzen. Die MTE hängt an Zeiger einen Schlüssel an, um deren Prozesszugehörigkeit zu markieren. Vor dem Zugriff auf den Speicherbereich, auf den der Zeiger verweist, prüft das System, ob die Markierung stimmt. Andernfalls löst es einen Trap aus und der unerlaubte Zugriff wird abgewiesen. Das mit der "Pointer Authentication" konkurrierende Konzept soll Angreifern das Manipulieren von Zeigern erschweren und auch Memory-Bugs frühzeitig erkennen helfen.

Der Veteran unter den Container-Technologien "User Mode Linux" (UML) erhält einen Treiber für PCI-over-virtio. Das Hostsystem kann mit diesem Treiber seine eigenen PCI-Treiber und -Geräte an die UML-Gäste durchreichen. Die PCI-Geräte können dann vollumfänglich in den UML-Gästen angesprochen werden.

In Linux 5.14 hat außerdem ein neuer Display-Treiber namens hyperv_drm für den Direct Rendering Manager (DRM) Einzug gehalten. Dieser Treiber ist für Microsofts Synthetic Video Device in Hyper-V gedacht und bringt gerade genügend Funktionalität mit, um "Kernel Mode Setting" (KMS) unter Hyper-V zum Laufen zu bringen. Er basiert im Wesentlichen auf dem bereits existierenden Framebuffer-Treiber hyperv_fb, arbeitet jedoch als DRM-Treiber auch mit Wayland zusammen. hyperv_drm stammt vermutlich aus den Bestrebungen Microsofts, auch grafische Applikationen unter WSL2 (Windows Subsystem for Linux 2) zu ermöglichen.

Ausblick und Nachtrag​

Seit dem Erscheinen von Linux 5.14 ist das Merge-Window für 5.15 offen. Die Entwickler können innerhalb der nächsten zwei Wochen Änderungen für das kommende Release einreichen. Schon vor dem Öffnen des Merge-Window galt übrigens als sicher, dass sich Linux 5.15 unter anderem mit den guten alten Diskettenlaufwerken befassen wird. Diese sind, wie die Linux-Entwicklercommunity in den letzten Monaten im Zuge vieldiskutierter Bugfixes erstaunt wahrnahm, noch immer Teil vieler älterer Systeme, die auf neue Kernel-Releases aktualisiert werden.

Abschließend ist noch erwähnenswert, dass die Problematik der sehr knappen End-of-Life-Frist des LTS (Long Term Support)-Kernels Linux 5.10, die wir
Du musst dich Anmelden oder Registrieren um diesen link zusehen!
ausführlich thematisiert haben, einen positiven Ausgang genommen hat: Dank Feedback und Hilfe aus der Community konnte das EoL-Datum des LTS-Kernels mittlerweile auf die üblichen sechs Jahre verlängert werden. Aktuell gehen die Kernel-Maintainer Greg Kroah-Hartman und Sasha Levin von einem EoL im Dezember 2026 aus.

Quelle: heise
 
Zurück
Oben