[LINUX] Kernel-Selbstschutz (1/2)

Ursprünglich ist es Teil des Quellcodes des Linux-Kernels, daher wird es als GPLv2 behandelt (Anerkennung, dass es sein sollte).

https://www.kernel.org/doc/html/latest/index.html

Licensing documentation

The following describes the license of the Linux kernel source code (GPLv2), how to properly mark the license of individual files in the source tree, as well as links to the full license text.

https://www.kernel.org/doc/html/latest/process/license-rules.html#kernel-licensing

https://www.kernel.org/doc/html/latest/security/self-protection.html

Kernel Self-Protection

Kernel self-protection is the design and implementation of systems and structures within the Linux kernel to protect against security flaws in the kernel itself.

Der Kernel-Selbstschutz wurde mit einem System und einer Struktur zum Schutz vor Sicherheitslücken im Linux-Kernel selbst entworfen und implementiert.

This covers a wide range of issues, including removing entire classes of bugs, blocking security flaw exploitation methods, and actively detecting attack attempts.

Es deckt eine breite Palette von Themen ab. Beseitigung der gesamten Fehlerklasse, Blockierung von Möglichkeiten zur Ausnutzung von Sicherheitslücken, Erkennung aggressiver Angriffsversuche und mehr.

Not all topics are explored in this document, but it should serve as a reasonable starting point and answer any frequently asked questions. (Patches welcome, of course!)

Dieses Dokument enthält nicht alle Themen, kann jedoch ein guter Ausgangspunkt oder für häufig gestellte Fragen sein (Patches sind natürlich willkommen!).

.

In the worst-case scenario, we assume an unprivileged local attacker has arbitrary read and write access to the kernel’s memory.

Im schlimmsten Fall wird davon ausgegangen, dass eine nicht autorisierte lokale Weihrauchansicht über beliebige Lese- / Schreibberechtigungen für den Kernelspeicher verfügt.

In many cases, bugs being exploited will not provide this level of access, but with systems in place that defend against the worst case we’ll cover the more limited cases as well.

In vielen Fällen bieten selbst ausgenutzte Fehler auf dieser Ebene keinen Zugriff. Ein System, das den schlimmsten Fall verhindern kann, kann jedoch noch begrenzte Fälle abdecken.

A higher bar, and one that should still be kept in mind, is protecting the kernel against a privileged local attacker, since the root user has access to a vastly increased attack surface.

Um diese Idee zu berücksichtigen, besteht eine höhere Ebene darin, den Kernel vor "privilegierten" lokalen Angreifern zu schützen. Als Root-Benutzer haben Sie Zugriff auf einen erheblich vergrößerten Angriffsbereich.

(Especially when they have the ability to load arbitrary kernel modules.)

(Vor allem, wenn sie ein beliebiges Kernelmodul laden können).

The goals for successful self-protection systems would be that they are effective, on by default, require no opt-in by developers, have no performance impact, do not impede kernel debugging, and have tests.

Das Erfolgsziel von Selbstschutzsystemen besteht darin, im Standardzustand effektiv testen zu können, ohne den Entwickler zu fragen, ohne die Leistung zu beeinträchtigen, das Debuggen und Testen zu beeinträchtigen. ..

It is uncommon that all these goals can be met, but it is worth explicitly mentioning them, since these aspects need to be explored, dealt with, and/or accepted.

Es ist nicht üblich, all diese Ziele zu erreichen, aber es ist erwähnenswert, dies zu erwähnen. Die Untersuchung muss durchgeführt oder akzeptiert werden.

Attack Surface Reduction

The most fundamental defense against security exploits is to reduce the areas of the kernel that can be used to redirect execution.

Der grundlegendste Schutz vor Sicherheitsmissbrauch besteht darin, den für die Umleitungsausführung verfügbaren Kernelbereich zu verkleinern.

This ranges from limiting the exposed APIs available to userspace, making in-kernel APIs hard to use incorrectly, minimizing the areas of writable kernel memory, etc.

Dies umfasst die Begrenzung der im Benutzerbereich verfügbaren verfügbaren APIs, die es schwieriger macht, versehentlich In-Kernel-APIs zu verwenden, die Menge des beschreibbaren Kernel-Speichers zu minimieren und vieles mehr. ..

Strict kernel memory permissions

When all of kernel memory is writable, it becomes trivial for attacks to redirect execution flow.

Wenn alle Kernel-Speicher beschreibbar sind, kann ein Angreifer den Ausführungsfluss leichter umleiten.

To reduce the availability of these targets the kernel needs to protect its memory with a tight set of permissions.

Um dieses Potenzial zu verringern, muss der Kernel seinen Speicher mit strengen Berechtigungen schützen.

Executable code and read-only data must not be writable

Any areas of the kernel with executable memory must not be writable.

Bereiche des Kernels mit ausführbarem Speicher dürfen nicht beschreibbar sein.

While this obviously includes the kernel text itself, we must consider all additional places too: kernel modules, JIT memory, etc.

Dies schließt natürlich den Kernel-Text selbst ein, aber Sie müssen auch den gesamten zusätzlichen Speicherplatz berücksichtigen. Kernelmodul, JIT-Speicher usw.

(There are temporary exceptions to this rule to support things like instruction alternatives, breakpoints, kprobes, etc.

(Es gibt Ausnahmen von dieser Regel, hauptsächlich zur Unterstützung von Anweisungen, Haltepunkten, kproves usw.

If these must exist in a kernel, they are implemented in a way where the memory is temporarily made writable during the update, and then returned to the original permissions.)

Wenn diese für den Kernel erforderlich sind, kann der Speicher während des Updates vorübergehend beschrieben und so implementiert werden, dass nach Abschluss der Aktualisierung die ursprünglichen Berechtigungen wiederhergestellt werden. )

In support of this are CONFIG_STRICT_KERNEL_RWX and CONFIG_STRICT_MODULE_RWX, which seek to make sure that code is not writable, data is not executable, and read-only data is neither writable nor executable.

Um dies zu unterstützen, gibt es CONFIG_STRICT_KERNEL_RWX und CONFIG_STRICT_MODULE_RWX. Diese stellen sicher, dass der Code nicht beschreibbar ist, die Daten nicht realisierbar sind und dass Daten, die nur gelesen werden können, nicht geschrieben oder ausgeführt werden können.

.

Most architectures have these options on by default and not user selectable.

Auf vielen Architekturen sind diese Optionen standardmäßig aktiviert und können nicht vom Benutzer ausgewählt werden.

For some architectures like arm that wish to have these be selectable, the architecture Kconfig can select ARCH_OPTIONAL_KERNEL_RWX to enable a Kconfig prompt.

Für einige Architekturen, wie z. B. Arm, können Sie nach Ihren Wünschen auswählen. Mit architecure Kconfig können Sie ARCH_OPTIONAL_KERNEL_RWX mit der Eingabeaufforderung Kconfig aktivieren.

CONFIG_ARCH_OPTIONAL_KERNEL_RWX_DEFAULT determines the default setting when ARCH_OPTIONAL_KERNEL_RWX is enabled.

Bestimmt CONFIG_ARCH_OPTIONAL_KERNEL_RWX_DEFAULT, wenn CONFIG_ARCH_OPTIONAL_KERNEL_RWX wirksam ist. .

Function pointers and sensitive variables must not be writable

Vast areas of kernel memory contain function pointers that are looked up by the kernel and used to continue execution

Ein großer Bereich des Kernelspeichers enthält Kernelzeiger, die vom Kernel abgerufen und zur Fortsetzung der Ausführung verwendet werden.

(e.g. descriptor/vector tables, file/network/etc operation structures, etc).

(Zum Beispiel Deskriptor- / Vektortabellen, Datei- / Netzwerk- usw. Operationsstrukturen usw.)

The number of these variables must be reduced to an absolute minimum.

Die Anzahl dieser Variablen muss auf das absolute Minimum reduziert werden.

.

Many such variables can be made read-only by setting them “const” so that they live in the .rodata section instead of the .data section of the kernel, gaining the protection of the kernel’s strict memory permissions as described above.

Viele dieser Variablen können durch Festlegen von const schreibgeschützt werden. Dadurch wird es im Abschnitt .rodata anstelle des Abschnitts .data des Kernels platziert. Geschützt durch die strengen Speicherberechtigungen des Kernels.

.

For variables that are initialized once at __init time, these can be marked with the (new and under development) __ro_after_init attribute.

Variablen, die während __init einmal initialisiert werden, können durch das Attribut __ro_after_init gekennzeichnet werden (falls neu oder in Entwicklung).

.

What remains are variables that are updated rarely (e.g. GDT).

Übrig bleiben nur Variablen, die selten aktualisiert werden (z. B. GDT).

These will need another infrastructure (similar to the temporary exceptions made to kernel code mentioned above) that allow them to spend the rest of their lifetime read-only.

Diese erfordern einen anderen Mechanismus, um sie während ihrer Lebensdauer schreibgeschützt verfügbar zu machen. (Ähnlich der temporären Ausnahme im oben gezeigten Kernel-Code).

(For example, when being updated, only the CPU thread performing the update would be given uninterruptible write access to the memory.)

(Zum Beispiel erhält der CPU-Thread zum Zeitpunkt der Aktualisierung eine ununterbrochene Schreibberechtigung für den Speicher.)

Segregation of kernel memory from userspace memory

The kernel must never execute userspace memory.

Der Kernel darf keinen User Space-Speicher ausführen.

The kernel must also never access userspace memory without explicit expectation to do so.

Der Kernel darf auch nicht ohne ausdrückliche Erwartung auf den Speicherplatz des Benutzers zugreifen.

These rules can be enforced either by support of hardware-based restrictions (x86’s SMEP/SMAP, ARM’s PXN/PAN) or via emulation (ARM’s Memory Domains).

Diese Regel wird durch einen hardwarebasierten Mechanismus (SMEP / SMAP für x86, PXN / PAN für ARM) erzwungen. Auch Emulation (Speicherdomänen für ARM).

By blocking userspace memory in this way, execution and data parsing cannot be passed to trivially-controlled userspace memory, forcing attacks to operate entirely in kernel memory.

Dies blockiert den Benutzerbereichsspeicher, was es unmöglich macht, leicht steuerbaren Benutzerbereichsspeicher als Ausführung oder Daten zu übergeben, was es unmöglich macht, überhaupt im Kernelspeicher anzugreifen.

Reduced access to syscalls

One trivial way to eliminate many syscalls for 64-bit systems is building without CONFIG_COMPAT. However, this is rarely a feasible scenario.

Eine einfache Möglichkeit, viele Systemaufrufe auf einem 64-Bit-System zu deaktivieren, besteht darin, ohne CONFIG_COMPAT zu erstellen. Dies ist jedoch ein selten realistisches Szenario.

.

The “seccomp” system provides an opt-in feature made available to userspace, which provides a way to reduce the number of kernel entry points available to a running process.

Das "seccom" -System bietet eine Anmeldefunktion, die Benutzerraum ermöglicht. Dies bietet eine Möglichkeit, die Anzahl der Kernel-Einstiegspunkte für laufende Prozesse zu reduzieren.

This limits the breadth of kernel code that can be reached, possibly reducing the availability of a given bug to an attack.

Dies kann den erreichbaren Bereich des Kernel-Codes einschränken und die Nützlichkeit der beim Angriff angegebenen Fehler verringern.

.

An area of improvement would be creating viable ways to keep access to things like compat, user namespaces, BPF creation, and perf limited only to trusted processes.

Der verbesserte Bereich bietet eine Möglichkeit, weiterhin den Zugriff auf Dinge wie Kompatibilität, BPF-Erstellung von Benutzernamensräumen und die Ausführung zuverlässiger Prozesse zu ermöglichen.

This would keep the scope of kernel entry points restricted to the more regular set of normally available to unprivileged userspace.

Dies beschränkt auch den Umfang des Kernel-Einstiegspunkts auf den Standardsatz, der normalerweise nicht autorisierten Benutzerbereichen zur Verfügung steht.

Restricting access to kernel modules

The kernel should never allow an unprivileged user the ability to load specific kernel modules, since that would provide a facility to unexpectedly extend the available attack surface.

Der Kernel darf nicht zulassen, dass nicht autorisierte Benutzer bestimmte Kernelmodule laden. Dies bietet die Möglichkeit, die Effektivität angreifbarer Aspekte zu erweitern, die Sie sich nie vorgestellt haben.

(The on-demand loading of modules via their predefined subsystems, e.g. MODULE_ALIAS_*, is considered “expected” here, though additional consideration should be given even to these.)

(Die Module, die "MODULE_ALIAS_ *" angeben und nach Bedarf geladen werden, sind die zuvor erwarteten Teilsysteme, die ebenfalls zusätzliche Überlegungen erfordern.)

For example, loading a filesystem module via an unprivileged socket API is nonsense: only the root or physically local user should trigger filesystem module loading.

Beispielsweise ist es nicht sinnvoll, das Dateisystemmodul aufzurufen, während eine nicht autorisierte Socket-API angezeigt wird. Nur Root- oder physisch lokale Benutzer sollten das Dateisystemmodul laden können.

(And even this can be up for debate in some scenarios.)

Und es gibt Raum, um einige Szenarien zu diskutieren.

.

To protect against even privileged users, systems may need to either disable module loading entirely (e.g. monolithic kernel builds or modules_disabled sysctl), or provide signed modules (e.g. CONFIG_MODULE_SIG_FORCE, or dm-crypt with LoadPin), to keep from having root load arbitrary kernel code via the module loader interface.

Das System muss möglicherweise das Laden von Modulen vollständig deaktivieren (als monolithischer Kernel oder modules_disable sysctl erstellen), um es auch vor privilegierten Benutzern zu schützen. Alternativ müssen Sie ein signiertes Modul verwenden (CONFIG_MODULE_SIG_FORCE und dm-crypt mit LoadPing). Dies verhindert, dass root Kernel-Code über eine Modullader-Schnittstelle lädt.

Memory integrity

There are many memory structures in the kernel that are regularly abused to gain execution control during an attack,

Der Kernel verfügt über eine häufig verwendete Speicherstruktur, um während eines Angriffs die Ausführungskontrolle zu erlangen.

By far the most commonly understood is that of the stack buffer overflow in which the return address stored on the stack is overwritten.

Das bisher am häufigsten verstandene ist ein Stapelpufferüberlauf, der die auf dem Stapel gespeicherte Rücksprungadresse überschreibt.

Many other examples of this kind of attack exist, and protections exist to defend against them.

Es gibt viele andere Beispiele für diese Art von Angriff, und es gibt Schutzmaßnahmen, um sie zu schützen.

Stack buffer overflow

The classic stack buffer overflow involves writing past the expected end of a variable stored on the stack, ultimately writing a controlled value to the stack frame’s stored return address.

Beim herkömmlichen Stapelpufferüberlauf wird schließlich versucht, durch Schreiben über das Ende des Yukata-Verkäufers der im Stapel gehaltenen Variablen hinaus die gesteuerte Adresse in die im Stapelrahmen gespeicherte Rücksprungadresse zu schreiben.

The most widely used defense is the presence of a stack canary between the stack variables and the return address (CONFIG_STACKPROTECTOR), which is verified just before the function returns.

Die am weitesten verbreitete Verteidigung besteht darin, einen Stapelkanarienvogel zwischen der Stapelvariablen und der Rücksprungadresse (CONFIG_STACKPROTECTOR) bereitzustellen. Dies wird unmittelbar vor der Rückkehr der Funktion bestätigt.

Other defenses include things like shadow stacks.

Ein weiterer Schutz besteht darin, einen Schattenstapel einzuschließen.

Stack depth overflow

A less well understood attack is using a bug that triggers the kernel to consume stack memory with deep function calls or large stack allocations.

Ein weniger bekannter Angriff besteht darin, einen Fehler zu verwenden, der den Kernel dazu veranlasst, Stapelspeicher durch umfangreiche Funktionsaufrufe oder große Stapelzuweisungen zu verbrauchen.

With this attack it is possible to write beyond the end of the kernel’s preallocated stack space and into sensitive structures.

Mit diesem Angriff können Sie über das Ende des vom Kernel reservierten Stapelspeichers hinaus in eine vertrauliche Struktur schreiben.

Two important changes need to be made for better protections: moving the sensitive thread_info structure elsewhere, and adding a faulting memory hole at the bottom of the stack to catch these overflows.

Für einen besseren Schutz sind zwei Modifikationen erforderlich. Verschieben der sensiblen thread_info-Struktur an einen anderen Speicherort und Hinzufügen eines Speicherlochs unter dem Stapel, falls der Überlauf nicht abgefangen werden kann.

Heap memory integrity

The structures used to track heap free lists can be sanity-checked during allocation and freeing to make sure they aren’t being used to manipulate other memory areas.

Die Struktur, die Heap-freie Listen verfolgt, kann während der Zuweisung und Freigabe auf Zustand überprüft werden, um sicherzustellen, dass sie nicht von anderen Speicherbereichsoperationen verwendet wird.

Counter integrity

Many places in the kernel use atomic counters to track object references or perform similar lifetime management.

In vielen Teilen des Kernels werden Atomzähler verwendet, um Objektreferenzen zu verfolgen und eine Lebensdauerverwaltung durchzuführen.

When these counters can be made to wrap (over or under) this traditionally exposes a use-after-free flaw.

Wenn dieser Zähler umwickelt (übermäßig oder zu klein), hat er lange Zeit einen Fehler verursacht, der nach dem Gebrauch frei ist.

By trapping atomic wrapping, this class of bug vanishes.

Durch das Abfangen von Atomverpackungen verschwindet diese Art von Fehler.

Size calculation overflow detection

Similar to counter overflow, integer overflows (usually size calculations) need to be detected at runtime to kill this class of bug, which traditionally leads to being able to write past the end of kernel buffers.

Ähnlich wie beim Zählerüberlauf sollte zur Laufzeit ein ganzzahliger Überlauf (normalerweise Größenberechnung) erkannt werden, um diese Art von Fehler zu beseitigen. Traditionell können Sie über das Ende des Kernelpuffers hinaus schreiben.

Weiter zur zweiten Hälfte ...

Es ist zu lang, der Rest ist die zweite Hälfte.

Recommended Posts

Kernel-Selbstschutz (1/2)
Kernel-Selbstschutz (2/2)
k-bedeutet und Kernel k-bedeutet
Kernel-Modus NEON
Kernel SVM (make_circles)