Linux Memory Protection Keys (MPK) – praktyczne wykorzystanie ochrony pamięci w Ubuntu i Debianie
Linux Memory Protection Keys (MPK) – praktyczne wykorzystanie ochrony pamięci w Ubuntu i Debianie
W nowoczesnych systemach Linux bezpieczeństwo pamięci stało się jednym z kluczowych elementów ochrony przed exploitami typu buffer overflow, use-after-free czy RCE (Remote Code Execution). Jednym z mechanizmów wprowadzonych w jądrze Linux (od wersji 5.1) jest Memory Protection Keys (MPK), umożliwiający dynamiczną kontrolę dostępu do pamięci na poziomie procesora.
Poniżej znajdziesz praktyczny przewodnik dla użytkowników Ubuntu i Debiana.
🧱 Czym jest Memory Protection Keys (MPK)?
MPK to mechanizm, który pozwala na:
- oznaczenie segmentów pamięci kluczami ochrony,
- kontrolę uprawnień odczytu i zapisu dla poszczególnych wątków,
- zmianę uprawnień w locie, bez przełączania kontekstu procesora,
- zwiększenie bezpieczeństwa aplikacji użytkownika i bibliotek.
Mechanizm działa w procesorach Intel z rozszerzeniem PKU (Protection Key for Userspace).
⚙️ Jak działa MPK w praktyce?
- System dzieli pamięć użytkownika na segmenty.
- Każdy segment otrzymuje klucz ochrony (Protection Key).
- Wątek, który próbuje uzyskać dostęp do segmentu, jest sprawdzany pod kątem uprawnień zapisanych w PKRU (Protection Key Rights Register).
Możliwe prawa dla segmentu pamięci:
| Flaga | Znaczenie |
|---|---|
R |
odczyt dozwolony |
W |
zapis dozwolony |
| brak | dostęp zabroniony |
Dzięki MPK można dynamicznie zmieniać prawa dostępu dla wątku, co pozwala np. na wstrzyknięcie bezpiecznych blokad w czasie działania programu.

🟦 Praktyczne zastosowanie w Ubuntu i Debianie
1️⃣ Instalacja narzędzi i nagłówków
sudo apt update
sudo apt install build-essential linux-headers-$(uname -r)
Nagłówki pozwalają korzystać z funkcji pkey_alloc, pkey_free, pkey_mprotect w kodzie C.
2️⃣ Tworzenie segmentu pamięci z MPK
#include <sys/mman.h>
#include <pkey.h>
#include <stdio.h>
#include <stdlib.h>
int main() {
size_t size = 4096;
void *addr = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
if (addr == MAP_FAILED) { perror("mmap"); exit(1); }
int pkey = pkey_alloc(0, 0);
if (pkey == -1) { perror("pkey_alloc"); exit(1); }
if (pkey_mprotect(addr, size, PROT_READ | PROT_WRITE, pkey) == -1) {
perror("pkey_mprotect"); exit(1);
}
printf("Segment memory przydzielony z Protection Key: %d\n", pkey);
return 0;
}
Ten prosty program:
- tworzy segment pamięci,
- przydziela mu MPK,
- ustawia prawa odczytu i zapisu.
3️⃣ Dynamiczna zmiana uprawnień w trakcie działania
#include <pkey.h>
pkey_set(pkey, PKEY_DISABLE_WRITE);
Dzięki temu wątek nie może już zapisywać do segmentu, ale odczyt jest dozwolony.
🛡 Zalety MPK
- ⚡ Wydajność – zmiana uprawnień w locie bez przełączania kontekstu jądra.
- 🔐 Bezpieczeństwo – izolacja segmentów pamięci, uniemożliwiająca zapis wrażliwych danych.
- 🧩 Łatwe integracje – można użyć w bibliotekach, sandboxach, interpreterach języków.
- 🧑💻 Debugowanie i testowanie – np. dynamiczne wyłączanie zapisu w trakcie testów bezpieczeństwa.
⚠️ Ograniczenia i uwagi
- MPK wymaga procesora z obsługą PKU (Intel Skylake i nowsze).
- Maksymalnie 16 kluczy ochrony na proces.
- Należy pamiętać o kompatybilności z innymi mechanizmami ochrony pamięci (ASLR, NX, SMEP).
- MPK nie chroni przed błędami w jądrze systemu – działa wyłącznie w przestrzeni użytkownika.
🔧 Praktyczne scenariusze zastosowania
- Izolacja stosu i sterty – uniemożliwienie nadpisania danych w trakcie exploitów.
- Bezpieczne interpretery języków – np. Python, Ruby mogą blokować dostęp do pamięci runtime wrażliwej na modyfikacje.
- Sandboksy dla pluginów – dynamiczna kontrola uprawnień pamięci w wtyczkach.
- Ochrona wrażliwych bibliotek – np. szyfrujące klucze, dane użytkownika w segmentach z ograniczonym zapisem.
📘 Podsumowanie
Linux Memory Protection Keys (MPK) to zaawansowany mechanizm ochrony pamięci, który pozwala na:
- dynamiczną kontrolę dostępu do segmentów pamięci,
- zwiększenie bezpieczeństwa aplikacji użytkownika,
- integrację z sandboxami i interpreteren języków,
- wydajne zarządzanie uprawnieniami bez spadku wydajności.
W Ubuntu i Debianie MPK może być używany zarówno w aplikacjach własnych, jak i w bibliotekach open-source, które chcą zapewnić dodatkową warstwę ochrony przed exploitami pamięci.






