2010-11-09 11 views
5

Come per il design linux su x86 e ppc, lo spazio di indirizzi virtuali 4g è diviso in 3: 1. Gli indirizzi virtuali degli utenti sono fino a 3g.Perché è richiesto copy_to/from_user?

Ora se l'app utente esegue un ioctl passando un puntatore al buffer, il modulo del kernel, può eseguire direttamente una memcpy, ho provato e ha funzionato. => Perché abbiamo quindi bisogno di un utente copy_to/copy_from.

Nota: se la pagina viene sostituita, il gestore di pagine del kernel restituisce tale elemento ed è invisibile al modulo del kernel.

bisogno di idee yr ... commenti

risposta

9

Ci sono molti buoni motivi che copy_to_user/copy_from_user sono le funzioni corrette da utilizzare:

  • Su alcune architetture un semplice memcpy() fa non lavoro, in modo da utilizzare queste funzioni consente il codice per lavorare lì. Credo che anche x86 con l'opzione di configurazione HIGHMEM selezionata sia in questa barca.

  • Queste funzioni fanno un controllo access_ok() per assicurare che gli indirizzi user space riferimento davvero sono veri indirizzi dello spazio utente. Se si fa semplicemente un memcpy(), il chiamante di ioctl() può fornire un intervallo di indirizzi che si sovrappone agli indirizzi del kernel, che è un buco di sicurezza.

  • Tuttavia, il motivo principale è gestire correttamente gli indirizzi utente non validi. Se si utilizza solo un valore di memcpy(), l'errore non gestito comporterà un errore del kernel. Le funzioni di accesso utente utilizzano "fixup" mechanism, che consente di gestire l'errore (la lettura o la scrittura è breve, e in genere in questo caso lo spazio EFAULT viene restituito allo spazio utente).

+0

ok, quindi il motivo principale è la gestione degli indirizzi ** bad **. – mSO

+0

e se gli indirizzi sono validi (diciamo il caso migliore, nessuno sta facendo del male) la memcpy dovrebbe funzionare. – mSO

+0

@Manish: Non è necessariamente "malizia", ​​potrebbe semplicemente essere un semplice vecchio bug in userspace - tali bug dovrebbero essere gestiti con garbo dal kernel. E il 'memcpy()' funzionerà solo su alcune architetture. – caf

0

sei stato fortunato ha funzionato.

Lo spazio utente e lo spazio del kernel operano in spazi di indirizzi completamente diversi. Quando si copia_to_utente il kernel converte gli spazi virtuali degli indirizzi utente in un vero indirizzo fisico e li copia lì. Un processo simile si verifica al contrario.

È possibile saltare direttamente la copia da/per passaggi se l'hardware supporta DMA scatter/gather. Qui mappare una parte contigua della memoria virtuale in una serie di pagine fisiche e quindi utilizzare tali informazioni in DMA direttamente nello spazio utente. Naturalmente questo ha delle complicazioni se uno qualsiasi degli spazi di indirizzamento virtuali non è attualmente mappato nella memoria fisica (think swap o file supportati da mmaps).

+0

la divisione 3g: 1g dovrebbe occuparsi di ciò. Il kernel AFAIK non ha bisogno di tradurre va in pa per la copia. – mSO

Problemi correlati