Come funziona mmap ' ing / dev / mem nonostante provenga da una modalità senza privilegi?
Su Febbraio 9, 2021 da adminPer quanto ne so, i programmi in spazio utente vengono eseguiti in modalità non privilegiata e quindi non hanno accesso diretto alla memoria o allI / O.
Allora come possiamo esattamente accedere direttamente alla memoria o alle posizioni I / O quando mmap / dev / mem nei programmi in spazio utente?
Ad esempio:
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);
Questo è un hack molto comunemente usato nei dispositivi embedded.
Ora la variabile leds
può essere usata al volo per accedere qualsiasi dispositivo che potrebbe essere presente a 0x80840000.
Non utilizzeremo più alcuna chiamata di sistema per accedere a quellindirizzo.
Anche qualcosa come
leds[0x20] = val;
funzionerebbe.
Ma le operazioni privilegiate, come la lettura / scrittura direttamente su / da un indirizzo I / O dovrebbero essere possibili solo mettendo il processore in modalità privilegiata tramite una chiamata di sistema.
Sorgente .
Commenti
Rispondi
Consentire laccesso a /dev/mem
da processi non privilegiati sarebbe effettivamente un problema di sicurezza e non dovrebbe essere consentito.
Sul mio sistema, ls -l /dev/mem
ha questo aspetto:
crw-r----- 1 root kmem 1, 1 Sep 8 10:12 /dev/mem
Quindi root
può leggerlo e scriverlo, membri del kmem
(di cui non ce nè nessuno) può leggerlo ma non scriverlo e tutti gli altri non possono aprirlo affatto. Quindi questo dovrebbe essere sicuro.
Se il tuo /dev/mem
è qualcosa di simile al mio, il tuo processo non privilegiato non avrebbe nemmeno dovuto essere in grado di aprire il file, figuriamoci mmap
it.
Controlla le autorizzazioni di /dev/mem
sul tuo sistema per assicurarti che siano sicure!
Commenti
- Ma supponendo che lo lo faccia come root … Significa che un processo eseguito da root ottiene il kernel privilegi di accesso a livello?
- Bene, se ' lo fai come root, allora hai accesso a tutto. ' non so cosa intendi per " privilegi di accesso a livello di kernel ", ma root può certamente fare tutto ciò che vuole, in un modo o nellaltro (in particolare, ad esempio, creando e caricando dinamicamente un nuovo modulo del kernel).
- Sì, ' è corretto: quando si mappa un file, in seguito si arriva a leggere & scrivere il file senza luso di alcuna chiamata ststem. Questo ' è vero se ' hai mappato un normale file su disco o un dispositivo speciale come
/dev/mem
. Se preferisci, puoi aprire/dev/mem
ed emettereread()
ewrite()
chiamate di sistema. Quindi non invieresti I / O senza luso di chiamate di sistema. Il risultato finale è lo stesso, ma se hai molte piccole operazioni di I / O da fare,mmap()
e laccesso diretto probabilmente funzioneranno meglio in particolare perché non ' Non servono chiamate di sistema! Questo vale anche per i file normali! - @ Stark07 Penso che ' non abbia capito il punto.
mmap
(e/dev/mem
) NON forniscono laccesso diretto al memoria di sistema, ed è impossibile farlo in Ring 4. Quello che fa invece è semplicemente mappare un file (o una risorsa) a uno specifico indirizzo virtuale nel processo chiamante, proprio come succede quando viene caricato un programma /exec
ed (in questo caso, limmagine del programma èmmap
edita nella memoria virtuale). - TL; DR Un processo senza privilegi non ha accesso diretto alla risorsa di sistema, ma può farlo quando quella risorsa è mappata al proprio spazio di indirizzi virtuale . Non cè ' alcuna differenza tra laccesso al suo stack / heap / rodata / qualunque e laccesso alla memoria del kernel – Alla fine entrambi accedono alla memoria fisica effettiva, mentre il secondo caso si trova semplicemente sotto il controllo del programma '.
Risposta
Gli indirizzi visibili a un processo utente (sia in esecuzione come utente root che come utente non privilegiato) sono indirizzi virtuali, che vengono mappati agli indirizzi fisici dalla MMU attraverso le tabelle delle pagine. Limpostazione delle tabelle delle pagine è unoperazione privilegiata e può essere eseguita solo dal codice del kernel; tuttavia, una volta impostate le tabelle delle pagine, laccesso alla memoria è consentito in modalità utente.
In concreto, il codice utilizza mmap
per richiedere che il kernel configuri il tabelle di pagina per consentire laccesso a un determinato intervallo di memoria fisica. Il kernel controlla i privilegi del processo (ha accesso in lettura / scrittura a /dev/mem
) e imposta le tabelle delle pagine per consentirgli di accedere alla memoria fisica.
Risposta
Il valore di leds
è un indirizzo virtuale. Fintanto che si trova nello spazio utente del processo corrente, il processo può accedervi direttamente tramite istruzioni come leds[0] = val
senza dover essere in modalità privilegiata, indipendentemente da dove nella RAM è mappato questo indirizzo virtuale
*
nella dichiarazione dileds
, ma questo ' è solo codice, nessuna prova del fatto che funzioni effettivamente come utente non privilegiato; nella mia (limitata) esperienza, tutto funziona come root su dispositivi incorporati.root
ha molti privilegi, incluso il permesso di sovrascrivere i tradizionali permessi del filesystem. Alcuni " file " consentono laccesso ai dispositivi (come il disco o la memoria), che sono vietati per gli utenti regolari. Nonroot
. Maroot
viene eseguito nello spazio utente , quindi ' non gode dei privilegi completi della modalità di sistema (esegue istruzioni privilegiate, principalmente).