Co to jest / dev / mem?

40

Przypuszczalnie ma to związek z pamięcią? Co by

sudo cat /dev/urandom > /dev/mem

robić? Kosz na całą pamięć RAM? Cała pamięć wirtualna inna niż jądro? Żadne z powyższych?

Cfinley
źródło
2
Zobacz także:dd if=/dev/urandom of=/dev/kmem bs=1 count=1 seek=$RANDOM
3490
6
Czy ochrona pamięci nie powinna zatrzymać dostępu do fizycznej pamięci RAM dla wszystkich procesów oprócz tej, która została przypisana do tego obszaru pamięci RAM? A może sudo zastępuje tę ochronę?
Matthew Lock

Odpowiedzi:

32

Zapewnia dostęp do fizycznej pamięci systemu.

mem(4)Strona podręcznika wyjaśnia więcej na temat tego, co /dev/memjest.

Tak - może to powodować różnego rodzaju problemy. Ponowne uruchomienie powinno Cię naprawić, ale złe rzeczy mogą się zdarzyć bardzo łatwo. Bądź ostrożny! :-)

Andrew Flanagan
źródło
4
Sugerowałbym przejrzenie strony man mem. Szmaty są poprawne. „mem jest plikiem urządzenia znakowego, który jest obrazem głównej pamięci komputera. Można go na przykład użyć do zbadania (a nawet załatania) systemu. Adresy bajtów w memie są interpretowane jako adresy pamięci fizycznej.” I ... „Plik kmem jest taki sam jak mem, z tym wyjątkiem, że dostępna jest pamięć wirtualna jądra, a nie pamięć fizyczna.”
Pan Shickadance
@Andrew Flanagan: Twój link pokazuje teraz, jak można ustawić stoper za pomocą polecenia czasowego.
Aiyion.Prime,
1
@ Aiyion.Prime. Dzięki - wskazał na wersję archive.org.
Andrew Flanagan,
19

/ dev / mem zapewnia dostęp do pamięci fizycznej systemu , a nie pamięci wirtualnej. Dostęp do wirtualnej przestrzeni adresowej jądra można uzyskać za pomocą / dev / kmem.

Jest używany głównie do uzyskiwania dostępu do adresów pamięci IO związanych ze sprzętem peryferyjnym, takim jak karty wideo.

łachmany
źródło
9

sudo cat /dev/urandom > /dev/memnic nie zrobi, ponieważ sudo podniesie przywilej kota, ale nie przekierowania. Możesz to zrobić, sudo sua następnie pracować w powłoce root lub użyć
sudo dd if=/dev/urandom of=/dev/mem

/dev/memzapewnia dostęp do pamięci fizycznej, tj. całej pamięci RAM w systemie, nie oznacza to jednak, że zapewnia pełny dostęp do odczytu / zapisu pamięci RAM (patrz opcja CONFIG_STRICT_DEVMEM w tym dokumencie). Należy również pamiętać, że w niektórych regionach pamięci fizycznej będą mapowane inne urządzenia, takie jak pamięć karty graficznej itp.

Pisanie na ślepo /dev/memspowoduje niepewne zachowanie, oto film z youtube robi to samo.

Sahil Singh
źródło
7

Przetestuj to za pomocą busybox devmem

busybox devmemto małe narzędzie CLI, które mmaps /dev/mem.

Możesz go pobrać w Ubuntu za pomocą: sudo apt-get install busybox

Zastosowanie: odczyt 4 bajty z adresu fizycznego 0x12345678:

sudo busybox devmem 0x12345678

Napisz 0x9abcdef0na ten adres:

sudo busybox devmem 0x12345678 w 0x9abcdef0

Źródło: https://github.com/mirror/busybox/blob/1_27_2/miscutils/devmem.c#L85

MAP_SHARED

Podczas mapowania /dev/memprawdopodobnie będziesz chciał użyć:

open("/dev/mem", O_RDWR | O_SYNC);
mmap(..., PROT_READ | PROT_WRITE, MAP_SHARED, ...)

MAP_SHARED powoduje, że zapisy trafiają natychmiast do pamięci fizycznej, co ułatwia obserwację i ma sens w przypadku zapisów rejestru sprzętowego.

CONFIG_STRICT_DEVMEM i nopat

Aby użyć /dev/memdo przeglądania i modyfikowania zwykłej pamięci RAM w jądrze v4.9, musisz:

  • wyłącz CONFIG_STRICT_DEVMEM(domyślnie ustawiony na Ubuntu 17.04)
  • przekaż nopatopcję wiersza poleceń jądra dla x86

Porty IO nadal działają bez nich.

Zobacz także: https://stackoverflow.com/questions/39134990/mmap-of-dev-mem-fails-with-invalid-argument-for-virt-to-phys-address-but-addre/45127582#45127582

Płukanie pamięci podręcznej

Jeśli spróbujesz zapisać w pamięci RAM zamiast rejestru, pamięć może być buforowana przez procesor: https://stackoverflow.com/questions/22701352/how-to-flush-the-cpu-cache-for-a-region -of-address-space-in-linux i nie widzę bardzo przenośnego / łatwego sposobu na opróżnienie go lub oznaczenie regionu jako niemożliwego do buforowania:

Więc może /dev/memnie może być niezawodnie używany do przekazywania buforów pamięci do urządzeń?

Niestety nie można tego zaobserwować w QEMU, ponieważ QEMU nie symuluje pamięci podręcznych.

Jak to przetestować

Teraz część zabawy. Oto kilka ciekawych konfiguracji:

  • Pamięć użytkownika
    • przypisz volatilezmienną do procesu użytkownika
    • uzyskaj adres fizyczny za pomocą /proc/<pid>/maps+/proc/<pid>/pagemap
    • adres fizyczny devmem2i obserwuj reakcję procesu użytkownika:
  • Pamięć Kernellanda
    • alokuj pamięć jądra za pomocą kmalloc
    • uzyskaj adres fizyczny virt_to_physi przekaż go z powrotem do obszaru użytkownika
    • zmień adres fizyczny za pomocą devmem2
    • zapytanie o wartość z modułu jądra
  • IO mem i urządzenie wirtualnej platformy QEMU
    • utwórz urządzenie platformy ze znanymi fizycznymi adresami rejestrów
    • użyj, devmem2aby zapisać do rejestru
    • zegarek printfs wyjdzie urządzenia wirtualnego w odpowiedzi
Ciro Santilli
źródło
5

/ dev / mem tradycyjnie zapewniał dostęp do całej fizycznej przestrzeni adresowej. Obejmuje to pamięć RAM, ale obejmuje także wszelkie urządzenia IO zmapowane w pamięci.

Wiele nowoczesnych jąder będzie skonfigurowanych z „CONFIG_STRICT_DEVMEM”, który ogranicza / dev / mem tylko do urządzeń IO zamapowanych w pamięci.

Zapisywanie losowych śmieci jest złym pomysłem, ale trudno przewidzieć, co dokładnie się stanie. Sprzęt może reagować w nieprzewidywalny sposób na przypadkowe śmieci, uszkodzone struktury pamięci jądra mogą powodować nieprzewidywalne zachowanie jądra. W najlepszym razie spodziewałbym się awarii systemu, w najgorszym przypadku uszkodzenia danych, a nawet blokowania sprzętu, nie jest wykluczone.

PS zauważ, że twoje polecenie uruchamiane jako zwykły użytkownik nie powinno nic robić, ponieważ sudo wymyka się tylko poleceniu cat, a nie przekierowaniu.

płyn do płukania
źródło