Hvordan fungerer mmap ' ing / dev / mem til tross for at de er i uprivilegert modus?
On februar 9, 2021 by adminSå langt jeg forstår, kjøres brukerplassprogrammer i en privilegert modus, og har dermed ikke direkte tilgang til minne eller I / O.
Hvordan kan vi da direkte få tilgang til minne eller I / O-steder når vi mmap / dev / mem i brukerromsprogrammer?
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 som ofte brukes i innebygde enheter.
Nå kan variabelen leds
brukes på farten for å få tilgang hvilken som helst enhet som kan være til stede på 0x80840000.
Vi bruker ikke noe systemanrop for å få tilgang til den adressen lenger.
Selv noe sånt som
leds[0x20] = val;
ville fungere.
Men privilegerte operasjoner, som å lese / skrive direkte til / fra en I / O-adresse, bør bare være mulig ved å sette prosessoren i privilegert modus gjennom et systemanrop.
Kilde .
Kommentarer
Svar
Tillater tilgang til /dev/mem
av ikke-privilegerte prosesser ville faktisk være et sikkerhetsproblem og burde ikke være tillatt.
På systemet mitt ser ls -l /dev/mem
slik ut:
crw-r----- 1 root kmem 1, 1 Sep 8 10:12 /dev/mem
Så root
kan lese og skrive det, medlemmer av kmem
gruppe (som det ikke er noen av) kan lese den, men ikke skrive den, og alle andre kan ikke åpne den i det hele tatt. Så dette skal være sikkert.
Hvis /dev/mem
er noe som min, burde den ubehagelige prosessen din ikke engang ha vært i stand til å åpne filen i det hele tatt, enn si mmap
det.
Kontroller tillatelsene til /dev/mem
på systemet ditt for å sikre at de er sikre!
Kommentarer
- Men forutsatt at jeg gjør dette som root … Betyr det at en prosess som kjøres av root får kjernen rettighetsnivå for rettigheter?
- Vel, hvis du ' gjør dette som root, har du tilgang til alt. Jeg ' er ikke sikker på hva du mener med " tilgangsrettigheter på kjernenivå ", men root kan absolutt gjøre alt den vil, på en eller annen måte (spesielt for eksempel ved å lage og dynamisk laste en ny kjernemodul).
- Ja, at ' er riktig: når du tilordner en fil, får du etterpå å lese & skrive filen uten bruk av ststemanrop. At ' stemmer om du ' har kartlagt en vanlig diskfil eller en spesiell enhet som
/dev/mem
. Hvis du foretrekker det, kan du åpne/dev/mem
og utstederead()
ogwrite()
systemanrop. Da vil du ikke sende I / U uten bruk av systemanrop. Sluttresultatet er det samme, men hvis du har mange små I / O-er å gjøre, vilmmap()
og direkte tilgang sannsynligvis fungere bedre spesielt fordi du ikke ' trenger ikke systemanrop! Dette gjelder også vanlige filer! - @ Stark07 Jeg tror du ' har savnet poenget.
mmap
(og/dev/mem
) gir IKKE direkte tilgang til systemminne, og det er umulig å gjøre det i Ring 4. Hva det gjør i stedet er bare å kartlegge en fil (eller ressurs) til en bestemt virtuell adresse i anropsprosessen, akkurat som det som skjer når et program lastes inn /exec
ed (i dette tilfellet blir programbildetmmap
redigert til det virtuelle minnet). - TL; DR En ikke-privilegert prosess har ikke direkte tilgang til systemressursen, men kan gjøre det når ressursen er kartlagt til deres virtuelle adresseområde . Det ' er ingen forskjell mellom å få tilgang til stack / heap / rodata / overhodet og få tilgang til kjerneminne – De får til slutt tilgang til det faktiske fysiske minnet, mens sistnevnte tilfelle tilfeldigvis er under program ' s kontroll.
Svar
Synlige adresser til en brukerprosess (enten kjører som root eller en ikke-sivilisert bruker) er virtuelle adresser, som blir kartlagt til fysiske adresser av MMU gjennom sidetabellene. Å sette opp sidetabellene er en privilegert operasjon, og kan bare utføres av kjernekode; når sidetabellene er angitt, er det imidlertid tillatt å få tilgang til minnet i brukermodus.
Konkret bruker koden din mmap
for å be om at kjernen konfigurerer sidetabeller for å gi tilgang til et gitt utvalg av fysisk minne. Kjernen sjekker prosessens rettigheter (den har lese- / skrivetilgang til /dev/mem
) og setter opp sidetabellene slik at den får tilgang til fysisk minne.
Svar
Verdien av leds
er en virtuell adresse. Så lenge den er i brukerområdet av den nåværende prosessen, kan prosessen få tilgang til den direkte via instruksjoner som leds[0] = val
uten å måtte være i privilegert modus, uansett hvor i RAM denne virtuelle adressen er kartlagt til
*
i erklæringen omleds
, men at ' bare er kode, ingen bevis for at dette faktisk fungerer som en uprivilegert bruker; i min (begrensede) erfaring, går alt som rot på innebygde enheter.root
brukeren har mange privilegier, som inkluderer å få lov til å overstyre tradisjonell filsystemtillatelser. Noen " filer " har virkelig tilgang til enheter (som disk eller minne), som ikke er tillatt for vanlige brukere. Ikkeroot
. Menroot
kjører i brukerområdet , så det nyter ikke ' alle rettighetene til systemmodus (utfør privilegerte instruksjoner, for det meste).