Hvordan fungerer mmap ' ing / dev / mem til trods for at være fra en privilegeret tilstand?
On februar 9, 2021 by adminFor så vidt min forståelse går, kører brugerrumsprogrammer i en privilegeret tilstand og har således ikke direkte adgang til hukommelse eller I / O.
Hvordan kan vi så direkte få adgang til hukommelse eller I / O-placeringer, når vi mmap / dev / mem i brugerrumsprogrammer?
For eksempel:
int fd = 0; u8 leds = 0; fd = open("/dev/mem", O_RDWR|O_SYNC); leds = (u8 *)mmap(0, getpagesize(), PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0x80840000);
Dette er et hack, der meget almindeligt bruges i indlejrede enheder.
Nu kan variablen leds
bruges i farten for at få adgang enhver enhed, der kan være til stede ved 0x80840000.
Vi bruger ikke længere et systemopkald for at få adgang til den adresse.
Selv noget som
leds[0x20] = val;
ville fungere.
Men privilegerede handlinger, såsom at læse / skrive direkte til / fra en I / O-adresse, skal kun være mulige ved at sætte processoren i privilegeret tilstand gennem et systemopkald.
Kilde .
Kommentarer
Svar
Tillader adgang til /dev/mem
af ikke-privilegerede processer ville faktisk være et sikkerhedsproblem og burde ikke være tilladt.
På mit system ser ls -l /dev/mem
sådan ud:
crw-r----- 1 root kmem 1, 1 Sep 8 10:12 /dev/mem
Så root
kan læse og skrive det, medlemmer af kmem
gruppe (hvor der tilfældigvis ikke er nogen) kan læse den, men ikke skrive den, og alle andre kan slet ikke åbne den. Så dette skal være sikkert.
Hvis din /dev/mem
er noget som min, skulle din ubehagelige proces ikke engang have været i stand til at åbne filen overhovedet, endsige mmap
det.
Kontroller tilladelserne for /dev/mem
på dit system for at sikre, at de er sikre!
Kommentarer
- Men forudsat at jeg gør dette som root … Betyder det, at en proces, der køres af root, får kernen adgangsrettigheder på niveau?
- Nå, hvis du ' gør dette som root, har du adgang til alt. Jeg ' er ikke sikker på, hvad du mener med " adgangsrettigheder på kerneniveau " root kan bestemt gøre alt, hvad den vil, på en eller anden måde (især f.eks. ved at lave og dynamisk indlæse et nyt kernemodul).
- Ja, at ' er korrekt: når du kortlægger en fil, får du bagefter at læse & skriver filen uden brug af ststemopkald. At ' er sandt, uanset om du ' har kortlagt en almindelig diskfil eller en speciel enhed som
/dev/mem
. Hvis du foretrækker det, kan du åbne/dev/mem
og udstederead()
ogwrite()
systemopkald. Så sender du ikke I / O uden brug af systemopkald. Slutresultatet er det samme, men hvis du har mange små I / O at gøre,mmap()
og direkte adgang vil sandsynligvis fungere bedre specifikt, fordi du ikke ' behøver ikke systemopkald! Dette gælder også for almindelige filer! - @ Stark07 Jeg tror, du ' har gået glip af pointen.
mmap
(og/dev/mem
) giver IKKE direkte adgang til systemhukommelse, og det er umuligt at gøre det i Ring 4. Hvad det i stedet gør er bare at kortlægge en fil (eller ressource) til en bestemt virtuel adresse i opkaldsprocessen, ligesom hvad der sker, når et program indlæses /exec
ed (i dette tilfælde er programbilledetmmap
ed til den virtuelle hukommelse). - TL; DR En ikke-privilegeret proces har ikke direkte adgang til systemressourcen, men kan gøre det, når denne ressource kortlægges til deres virtuelle adresseområde . Der ' er der ingen forskel mellem at få adgang til dens stack / heap / rodata / overhovedet og få adgang til kernen hukommelse – De får i sidste ende begge adgang til den faktiske fysiske hukommelse, mens sidstnævnte tilfælde tilfældigvis bare er under program ' s kontrol.
Svar
Synlige adresser til en brugerproces (hvad enten de kører som root eller en ikke-civiliseret bruger) er virtuelle adresser, som bliver tilknyttet til fysiske adresser af MMU gennem sidetabellerne. Opsætning af sidetabeller er en privilegeret handling og kan kun udføres med kernekode; når først sidetabellerne er indstillet, er adgang til hukommelsen dog tilladt i brugertilstand.
Konkret bruger din kode mmap
til at anmode om, at kernen opretter sidetabeller for at give adgang til et givet interval af fysisk hukommelse. Kernen kontrollerer procesens privilegier (den har læse- / skriveadgang til /dev/mem
) og indstiller sidetabellerne for at give den adgang til fysisk hukommelse.
Svar
Værdien af leds
er en virtuel adresse. Så længe det er i brugerrummet i den aktuelle proces kan processen få adgang til den direkte via instruktioner som leds[0] = val
uden at skulle være i privilegeret tilstand, uanset hvor i RAM denne virtuelle adresse er kortlagt til
*
i erklæringen omleds
, men at ' bare er kode, intet bevis for, at dette faktisk fungerer som en privilegeret bruger; i min (begrænsede) oplevelse kører alt som rod indlejrede enheder.root
brugeren har mange privilegier, som inkluderer at have lov til at tilsidesætte traditionelle tilladelser til filsystemer. Nogle " filer " har virkelig adgang til enheder (som disk eller hukommelse), som ikke er tilladt for almindelige brugere. Ikkeroot
. Menroot
kører i brugerrum , så det nyder ikke ' ikke de fulde privilegier i systemtilstand (udfør for det meste privilegerede instruktioner).