Libseccomp: RFE: "Maximale Kernel-Version" unterstützen

Erstellt am 21. Aug. 2015  ·  14Kommentare  ·  Quelle: seccomp/libseccomp

Wenn dem Kernel Systemaufrufe hinzugefügt werden, wird meines Erachtens standardmäßig nicht genug über die Vielzahl von Anwendungen gesprochen, die plötzlich Zugang zu einer neuen Angriffsfläche erhalten.

Das kanonische Beispiel hier ist perf_event_open() , die Quelle zahlreicher CVEs. Während perf großartig ist, sollte mein (z. B.) Webserver (standardmäßig) nicht in der Lage sein, es zu verwenden.

Es ist möglich, seccomp heute zu verwenden, um auf die schwarze Liste zu setzen. Whitelists können sehr schwierig zu verwalten sein.

Eine Sache, die nützlich sein könnte, ist ein Filter für alle Systemaufrufe, die neuer als eine bestimmte Kernel-Version sind, sagen wir 3.10. Auf diese Weise müsste jeder neue Systemaufruf für die Verwendung in zB Containern verifiziert werden, bevor er hinzugefügt wird. Ein Upgrade des Kernels würde Container nicht plötzlich einer neuen Angriffsfläche aussetzen.

In einer Diskussion mit @pcmoore wies er darauf hin, dass dies eine weitere Anmerkung in der Struktur in zB arch-x86-syscalls.c sein könnte.

enhancement pendininfo prioritmedium

Hilfreichster Kommentar

Es sieht so aus, als ob Ausgabe Nr. 286 das konkrete Problem ist, um diese Arbeit voranzutreiben ... auch wenn es fast fünf Jahre her sind ;)

Ich denke, der erste Schritt in diese Richtung besteht darin, der Datei syscalls.csv ein neues Feld hinzuzufügen, das angibt, wann der Systemaufruf zum ersten Mal eingeführt wurde. Das wird ein gutes Stück Arbeit, da wir derzeit ~469 Systemaufrufe definiert haben (!). Allerdings könnten wir diese Arbeit für die bestehenden Systemaufrufe mit einem "undefinierten" Wert amortisieren, den wir einfach so behandeln würden, als würde der Systemaufruf zu Beginn der Zeit erstellt. Natürlich müssten alle neuen Ergänzungen zur Tabelle syscalls.csv mit der Kernel-Version hinzugefügt werden.

Noch ein paar schnelle Gedanken:

  • syscall.csv-Format
#syscall (v5.8.0-rc5 2020-07-14),kver_min,x86,x86_64,...
accept,<version>,PNR,43,...

... wobei <version> so etwas wie "5_8", "UNDEF" oder ähnliches sein könnte.

  • Versionstoken
enum kernel_version {
    KV_UNDEF = 0,
    KV_1_0,
    KV_1_1,
    KV_1_3,
    KV_2_0,
    ...
    KV_5_8,
    _KV_MAX,
};

Alle 14 Kommentare

+1
Das würde helfen, Blacklists für die Minderung von Sicherheitsproblemen nutzbar zu machen.

@nmav Um es klar zu sagen, dieses RFE dient zum Hinzufügen von Informationen zu den internen Syscall-Tabellen darüber, wann der Syscall zum ersten Mal in den Linux-Kernel eingeführt wurde, und nicht zum Hinzufügen von Logik, um festzustellen, ob der aktuell ausgeführte Kernel einen bestimmten Syscall unterstützt. Wenn Sie jedoch versuchen, einen Systemaufruf zu blockieren, können Sie dies mit libseccomp tun, unabhängig davon, ob es von einer bestimmten Arch/ABI- und Kernel-Version unterstützt wird, libseccomp wird das Richtige für Sie tun.

Dieses RFE ist fast fünf Jahre alt, und abgesehen von einer einzigen Diskussion mit @cgwalters habe ich kein großes Interesse an einer solchen Funktion gesehen oder gehört. Bei vielen anderen offenen Themen, die meisten mit höherer Priorität, ist nicht klar, wann wir daran arbeiten würden, oder ob so etwas eine sinnvolle Ergänzung wäre.

@cgwalters und @drakenclimber was hältst du von dieser Ausgabe im Jahr 2020? Ich bin versucht, dies als WONTFIX zu schließen, aber ich würde gerne einige Kommentare und Rückmeldungen erhalten, bevor wir diesen Schritt unternehmen.

@cgwalters und @drakenclimber was hältst du von dieser Ausgabe im Jahr 2020? Ich bin versucht, dies als WONTFIX zu schließen, aber ich würde gerne einige Kommentare und Rückmeldungen erhalten, bevor wir diesen Schritt unternehmen.

Ehrlich gesagt finde ich das eine echt coole Idee. Mehrere meiner internen Kunden verwenden genau aus diesem Grund Zulassungslisten. Wenn sie eine Denylist verwenden und dem Kernel ein neuer Syscall hinzugefügt wird, dann wäre dieser Syscall ein weiterer Angriffspunkt.

Lassen wir es noch ein bisschen offen. Ich werde mich bei Oracle umhören und sehen, ob Kunden genug Interesse an dieser Funktion haben, damit ich sie abholen kann. Aber @cgwalters (oder sonst jemand) kann es gerne besitzen, wenn er Zeit und Interesse hat :).

Okay, solange es Interesse gibt, habe ich kein Problem damit, dieses hier offen zu halten.

Ich denke immer noch, dass es nützlich wäre!

Es sieht so aus, als ob Ausgabe Nr. 286 das konkrete Problem ist, um diese Arbeit voranzutreiben ... auch wenn es fast fünf Jahre her sind ;)

Ich denke, der erste Schritt in diese Richtung besteht darin, der Datei syscalls.csv ein neues Feld hinzuzufügen, das angibt, wann der Systemaufruf zum ersten Mal eingeführt wurde. Das wird ein gutes Stück Arbeit, da wir derzeit ~469 Systemaufrufe definiert haben (!). Allerdings könnten wir diese Arbeit für die bestehenden Systemaufrufe mit einem "undefinierten" Wert amortisieren, den wir einfach so behandeln würden, als würde der Systemaufruf zu Beginn der Zeit erstellt. Natürlich müssten alle neuen Ergänzungen zur Tabelle syscalls.csv mit der Kernel-Version hinzugefügt werden.

Noch ein paar schnelle Gedanken:

  • syscall.csv-Format
#syscall (v5.8.0-rc5 2020-07-14),kver_min,x86,x86_64,...
accept,<version>,PNR,43,...

... wobei <version> so etwas wie "5_8", "UNDEF" oder ähnliches sein könnte.

  • Versionstoken
enum kernel_version {
    KV_UNDEF = 0,
    KV_1_0,
    KV_1_1,
    KV_1_3,
    KV_2_0,
    ...
    KV_5_8,
    _KV_MAX,
};

Ist die Kernel-Version das Richtige zum Nachverfolgen? Ist garantiert, dass neuere Systemaufrufe nicht auf zB Stable-Kernel-Zweige mit einer niedrigeren Versionsnummer zurückportiert werden?

Red Hat wird alle möglichen Dinge in seine Kernel zurückportieren, also nein.

Wenn RedHat einen Systemaufruf auf eine ältere Kernel-Version zurückportiert, können sie auch ihre Version von libseccomp entsprechend patchen. Um fair zu sein, könnte dies für bestimmte Anwendungsfälle wichtiger sein, aber als Ansatz zur Behebung von # 286 denke ich, dass es ziemlich praktikabel ist. Das andere Problem ist, dass ich nicht sicher bin, ob es einen besseren Ansatz gibt - Systemaufrufe können in nicht aufeinanderfolgender Reihenfolge hinzugefügt werden (zum Beispiel wurde openat2 vor close_range hinzugefügt - obwohl dieses Beispiel nett ist meiner Schuld).

Wenn RedHat einen Systemaufruf auf eine ältere Kernel-Version zurückportiert, können sie auch ihre Version von libseccomp entsprechend patchen.

Ja genau. Das Upstream-Projekt libseccomp hat keine Kontrolle über die verschiedenen Enterprise-Linux-Distributionen, und wenn sich diese Distributionen entscheiden, von den Upstream-Projekten (entweder dem Linux-Kernel oder libseccomp) abzuweichen, sind sie für den Support auf sich allein gestellt. Obwohl wir unser Bestes tun werden, um zu helfen, können wir das Upstream-Projekt nicht zugunsten dieser Enterprise-Distributionen mit ihrem eigenen Support- und Technikpersonal opfern.

Als Referenz enthält die syscalls(2) -Manpage einige historische Informationen darüber, wann verschiedene Systemaufrufe in den Kernel eingeführt wurden:

Ich kann die Syscall-Spelunking durchführen, um eine Versionsnummer für jeden Syscall herauszufinden - die einzige Frage ist, ob wir die Versionsnummer pro Architektur haben sollten, da ich mir ziemlich sicher bin, dass bestimmte Syscalls zu verschiedenen Architekturen in verschiedenen Releases hinzugefügt wurden.

... die einzige Frage ist, ob wir die Versionsnummer pro Architektur haben sollten, da ich mir ziemlich sicher bin, dass bestimmte Syscalls zu verschiedenen Architekturen in verschiedenen Releases hinzugefügt wurden.

Sie waren es auf jeden Fall und sind es immer noch, soweit ich sehen kann. Während es etwas lästig sein wird und definitiv die CSV explodieren wird, ist es wahrscheinlich das Richtige, das erste Erscheinen des Systemaufrufs für jeden Arch/ABI zu verfolgen.

Jede Hilfe, die Sie zu diesem @cyphar leisten können, wäre sehr willkommen.

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen