Hoe werkt mmap ' ing / dev / mem ondanks dat het zich in de onbevoegde modus bevindt?
Geplaatst op februari 9, 2021 door adminVoor zover ik weet, draaien gebruikersruimteprogrammas in de onbevoegde modus en hebben ze dus geen directe toegang tot geheugen of I / O.
Hoe kunnen we dan precies rechtstreeks toegang krijgen tot geheugen of I / O-locaties als we mmap / dev / mem in gebruikersruimteprogrammas gebruiken?
Bijvoorbeeld:
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);
Dit is een hack die heel vaak wordt gebruikt in embedded apparaten.
Nu kan de variabele leds
direct worden gebruikt om toegang te krijgen tot elk apparaat dat aanwezig zou kunnen zijn op 0x80840000.
We zullen “geen systeemoproep meer gebruiken om toegang te krijgen tot dat adres.
Zelfs zoiets als
leds[0x20] = val;
zou werken.
Maar geprivilegieerde bewerkingen, zoals rechtstreeks lezen / schrijven naar / van een I / O-adres zouden alleen mogelijk moeten zijn door de processor in geprivilegieerde modus te brengen via een systeemoproep.
Bron .
Reacties
Antwoord
Toegang verlenen tot /dev/mem
door onbevoegde processen zou inderdaad een beveiligingsprobleem zijn en zou niet moeten worden toegestaan.
Op mijn systeem ziet ls -l /dev/mem
er als volgt uit:
crw-r----- 1 root kmem 1, 1 Sep 8 10:12 /dev/mem
Dus root
kan het lezen en schrijven, leden van de kmem
group (waarvan er toevallig geen zijn) kan het lezen maar niet schrijven, en alle anderen kunnen het helemaal niet openen. Dus dit zou veilig moeten zijn.
Als uw /dev/mem
zoiets als de mijne is, zou uw onbevoegde proces het bestand helemaal niet moeten kunnen openen, laat staan mmap
it.
Controleer de rechten van /dev/mem
op uw systeem om er zeker van te zijn dat ze veilig zijn!
Reacties
- Maar aangenomen dat ik doe dit als root doe … Betekent dit dat een proces dat door root wordt uitgevoerd de kernel krijgt niveau toegangsprivileges?
- Nou, als je ' dit als root doet, heb je toegang tot alles. Ik ' m niet zeker wat u bedoelt met " toegangsrechten op kernelniveau ", maar root kan zeker alles doen wat het wil, op de een of andere manier (in het bijzonder bijvoorbeeld door een nieuwe kernelmodule te maken en dynamisch te laden).
- Ja, dat ' s correct: als je een bestand in kaart brengt, krijg je daarna & te lezen, schrijf het bestand zonder het gebruik van enige aanroepen van de standaard. Dat ' is waar of je ' een normaal schijfbestand of een speciaal apparaat zoals
/dev/mem
. Als u wilt, kunt u/dev/mem
openen enread()
enwrite()
systeemoproepen uitvoeren. Dan zou u geen I / O verzenden zonder het gebruik van systeemoproepen. Het eindresultaat is hetzelfde, maar als u veel kleine I / O te doen heeft, zullenmmap()
en directe toegang waarschijnlijk beter presteren, vooral omdat u ' geen systeemoproepen nodig! Dit geldt ook voor gewone bestanden! - @ Stark07 Ik denk dat je ' het punt gemist hebt. De
mmap
(en/dev/mem
) zelf bieden GEEN directe toegang tot de systeemgeheugen, en het is onmogelijk om dit te doen in Ring 4. Wat het in plaats daarvan doet, is gewoon een bestand (of bron) toewijzen aan een specifiek virtueel adres in het aanroepproces, net zoals wat er gebeurt wanneer een programma wordt geladen /exec
ed (in dit geval is de programma-afbeeldingmmap
ed naar het virtuele geheugen). - TL; DR Een onbevoegd proces heeft geen directe toegang tot systeembronnen, maar kan dit doen wanneer die bron is toegewezen aan hun virtuele adresruimte . Er ' s geen verschil tussen toegang tot de stack / heap / rodata / wat dan ook en toegang tot het kernelgeheugen – Ze hebben uiteindelijk allebei toegang tot het daadwerkelijke fysieke geheugen, terwijl het laatste geval toevallig onder het programma ' s controle.
Antwoord
De zichtbare adressen naar een gebruikersproces (of het nu als root of een onbevoegde gebruiker draait) zijn virtuele adressen, die door de MMU aan fysieke adressen worden toegewezen via de paginatabellen. Het opzetten van de paginatabellen is een geprivilegieerde bewerking en kan alleen worden uitgevoerd door kernelcode; als de paginatabellen eenmaal zijn ingesteld, is toegang tot het geheugen toegestaan in de gebruikersmodus.
Concreet gebruikt uw code mmap
om de kernel te vragen de paginatabellen om toegang te krijgen tot een bepaald bereik van fysiek geheugen. De kernel controleert de privileges van het proces (het heeft lees- / schrijftoegang tot /dev/mem
) en stelt de paginatabellen in om toegang te krijgen tot fysiek geheugen.
Answer
De waarde van leds
is een virtueel adres. Zolang het maar in de gebruikersruimte staat van het huidige proces, heeft het proces er rechtstreeks toegang toe via instructies zoals leds[0] = val
zonder in geprivilegieerde modus te hoeven zijn, ongeacht waar in het RAM dit virtuele adres is toegewezen aan
*
mist in de declaratie vanleds
, maar dat ' is gewoon code, geen bewijs dat dit daadwerkelijk werkt als een onbevoegde gebruiker; in mijn (beperkte) ervaring draait alles als root op ingesloten apparaten.root
-gebruiker heeft veel privileges, waaronder de mogelijkheid om traditionele bestandssysteemrechten. Sommige " bestanden " hebben echt toegang tot apparaten (zoals schijf of geheugen), die niet toegankelijk zijn voor gewone gebruikers. Nietroot
. Maarroot
draait in gebruikersruimte , dus ' geniet niet van de volledige rechten van de systeemmodus (voer meestal geprivilegieerde instructies uit).