implicazioni di sicurezza della dereferenza NULL

11

Supponiamo di avere un codice come questo:

struct somedata {
   int a;
   int b;
};
struct somedata *data;
/* ... */
data = malloc(sizeof(struct somedata));
data->a = something;

Ora, come puoi vedere, manca il controllo del puntatore NULL. La domanda è: questo ha implicazioni di sicurezza nel caso in cui Malloc fallisce? Supponiamo che il processo in uscita su SEGV da solo non sia un problema in questo caso. C'è un altro modo in cui questo può essere un problema dal punto di vista della sicurezza? L'applicazione che contiene questo codice non è SUID o con privilegi elevati, ma elabora input esterni, quindi alcune parti della sua memoria possono essere controllate dall'utente.

P.S. Sono a conoscenza di CWE-476 ma le implicazioni sulla sicurezza sono descritte in modo molto vago ("In circostanze e ambienti molto rari, l'esecuzione del codice è possibile "- quali circostanze? quali ambienti? Quanto raro - colpire la meteora-tu-in-the-head rari o rari una volta all'anno?) e mi piacerebbe vederne alcuni informazioni più specifiche su quale sia la minaccia.

    
posta StasM 28.07.2011 - 19:00
fonte

2 risposte

8

"Il processo in uscita su SEGV da solo non è un problema in questo caso": questo è già un grande presupposto. Qualunque cosa stia facendo il processo non sarà finita; il chiamante riceve un codice di errore; se il processo ha creato file temporanei, quei file non vengono cancellati. Assicurarti che non ci siano davvero problemi è difficile.

Inoltre, ciò che crea il SEGV è l'accesso a un'area di memoria che il sistema operativo ha deliberatamente contrassegnato come non valido; vale a dire, la prima "pagina" dello spazio degli indirizzi (una pagina è 4096 byte su un PC). Considera quanto segue:

data = malloc(1000000 * sizeof(struct somedata));
data[800000].a = something;

Se struct somedata ha una lunghezza di 8 byte e l'allocazione fallisce, il codice proverà a scrivere qualcosa all'indirizzo +6400000. Anche se il sistema operativo non ha mappato i primi 4096 byte, è possibile che l'indirizzo 6400000 sia valido e utilizzato per qualcos'altro, che viene automaticamente sovrascritto. A quel punto, tutto va bene. Anche in questo caso, sapere se un dato NULL restituito da malloc() implicherebbe un'immediata segfault o la corruzione silenziosa può essere difficile.

Se il processo non ha diritti speciali e l'autore dell'attacco ha già il potere di eseguire file eseguibili con gli stessi privilegi, quindi non controllare il valore restituito da malloc() non rivela nuovi problemi di sicurezza. È solo sciatto.

    
risposta data 28.07.2011 - 19:23
fonte
5

Nel codice del kernel, questo bug è una grave vulnerabilità . Il codice utente può richiedere di rimappare la pagina a partire dall'indirizzo 0 e tale mappatura si applicherà anche al codice del kernel. Quindi, se questo accade, il kernel sta ora leggendo da (o scrivendo a) memoria controllata dall'utente invece di memoria controllata dal kernel, che potrebbe violare l'integrità (o riservatezza) del calcolo dei kernel. Ad esempio, se il kernel legge un puntatore da questa pagina e poi la dereferenzia, possono accadere cose molto brutte. Pertanto, questo tipo di bug può abilitare l'escalation dei privilegi, consentendo a un processo utente non root dannoso di attaccare il kernel e fare cose che non dovrebbero essere autorizzati a fare.

Nel codice dell'applicazione a livello utente, questo bug non è di solito un problema di sicurezza, perché non è possibile che un utente malintenzionato possa re-mappare lo zero della pagina senza la cooperazione dell'applicazione. (Eccezione: ci sono alcune applicazioni che rimappano deliberatamente la pagina a partire dall'indirizzo 0. Penso, ad esempio, a Wine. Non so se ci sono implicazioni di sicurezza per quelle applicazioni eccezionali.)

Grazie a @ this.josh per il collegamento a una spiegazione della vulnerabilità nel codice a livello di kernel.

    
risposta data 03.08.2011 - 00:00
fonte

Leggi altre domande sui tag