Cos'è Stack Smashing?? Si può aggiustare?

Contenuti

mucchio di monete che rompono la palla

Ogni minuto di fermo della produzione generalmente costa denaro all'azienda. Se la tua applicazione ha un serio ostacolo che causa la rottura della batteria, è in viaggio. Scopri in anticipo cos'è la distruzione della batteria e cosa si può fare al riguardo!!

Che cos'è Distruggere lo stack?

Lavorare come ingegnere di assicurazione della qualità, prima o poi ci si imbatte nel termine schiacciare il mucchio. Come sviluppatore, è probabile che questo termine venga scoperto anche prima, soprattutto se è stato inserito un errore nel codice, cosa causa una batteria rotta?. È relativamente facile (come in 'qualcosa di facile’) che uno sviluppatore commetta un errore che introduce la rottura della batteria. Come utente, quando imparo a rompere le batterie, il danno è probabilmente già fatto.

La rottura della batteria può verificarsi involontariamente, come esempio, quando lo sviluppatore ha introdotto un bug che ha causato l'arresto anomalo dello stack, o maliziosamente, un utente malintenzionato che in qualche modo cerca di traboccare o corrompere lo stack di un programma.

Lo stack smashing è una definizione con una definizione un po' vaga che può indicare vari problemi e può provenire da una serie di fonti. I due problemi più importanti che possono causare la rottura della batteria sono; 1) scrivere / sovraallocazione di troppi dati in una data parte dello stack, sovrascrivendo così un'altra parte dello stack, e 2) dove qualche fonte esterna (dannoso o no) sovrascritto lo stack di un altro programma, anche se questo è molto meno comune .

Quindi, Cos'è una pila? Anche questa è una definizione vagamente definita. In termini generali, uno stack si riferisce a uno stack di elaborazione del programma, uno stack di funzioni definite in un programma / codice software fornito.

Inizia immaginando una pila di piastrelle del bagno impilate, pronto per essere utilizzato da un piastrellista. Questa è una rappresentazione abbastanza buona di una pila di computer., con qualche modifica. Se ogni mosaico fosse un po' spostato dal precedente, sarebbe un'immagine migliore, e presto vedremo perché.

Immagina che ogni tessera impilata sia una funzione nel programma del computer. La funzione più elementare è in fondo e potrebbe essere, come esempio, il main() funzione in un programma C o C ++. C e C ++ sono due linguaggi di programmazione che utilizzano ampiamente lo stack.

Ognuna di queste funzioni nel programma C / C ++ avrà un nome e probabilmente un insieme di variabili in entrata e in uscita. In termini semplificati, immagina se una di quelle variabili avesse una lunghezza di 10 caratteri e qualche altra funzione digitata accidentalmente 100 caratteri in quella variabile. Questo può danneggiare l'intero stack..

In termini di esempio di piastrella sopra, immagina qualcuno con un martello che colpisce troppo forte la prima tessera e quindi rompe tutte le altre tessere. ecco qua; rottura del mucchio 😉

L'analogia funziona perché, proprio come tutte le tessere sono ora rotte nella nostra immagine di memoria fittizia, una batteria rotta risulterà in "Funzioni interrotte"’ Se fai finta. Ogni offset delle tessere è una funzione nidificata più profondamente; maggiori informazioni sulle funzioni interrotte nella prossima sezione.

Depurazione Batteria (S) in frantumi

Considerando che tecnicamente un riferimento a "Funzioni interrotte"’ potrebbe non essere del tutto corretto, In altre parole, probabilmente c'è solo una funzione interrotta, e potrebbe anche non esserci una funzione interrotta quando c'è un attacco esterno o un programma malfunzionante, è un ottimo modo per pensare a una batteria rotta.

Ad un tratto, i nomi delle variabili e delle funzioni possono essere modificati, c'è un backtrace (il flusso di funzioni che il computer ha impiegato per arrivare a una data funzione che si è bloccata, e (nel nostro esempio) ha rotto la pila) non ha più senso.

In termini generali, quando osserviamo un backtrace, avrà un chiaro flusso di funzioni che sono state chiamate. Sebbene un programma fallito non possa essere immediatamente definito "sano", in termini di rinculo / depurazione, ecco come appare un "sano" ritorno al passato:

Uno stack "sano" tramite backtrace (bt) usando GDB

Nonostante questo, quando una batteria è scarica, il debug diventa molto più difficile. Lo stack può assomigliare a questo:

Un dump dello stack schiacciante generato da mysqld, il server di database MySQL

Questo è un esempio di un problema di interruzione dello stack che si è verificato in MySQL, il server della banca dati (Chiedi a log.txt allegato a Errore di MySQL 37815 per la piena uscita) Su 2008, che ha causato il demone del server di database (mysqld) finire.

Mentre la libreria del sistema operativo libc.so.6, in questa circostanza, sembra aver gestito abbastanza bene lo stack di rottura (utilizzando alcune funzionalità di fortificazione nel __fortify_fail funzione), il problema esisteva da qualche parte nel codice e da allora è stato risolto.

Si noti inoltre che in questa circostanza, non vediamo i nomi delle funzioni risolti, ci viene mostrato solo il nome binario (curiosamente, il problema sembra essere stato con il cliente (mysql) causando il server (mysqld) finire) Che cos'è mysql, insieme a un indirizzo di memoria della funzione: mysql[0x8051565], mysql[0x80525c7] e mysql(main+0x4f8)[0x8053198].

Regolarmente, quando usiamo i simboli di debug (vedi sotto un post su GDB che spiega cosa sono i simboli di debug in dettaglio), vedremmo nomi di funzioni con variabili, e anche con alcuni livelli di ottimizzazione / minimizzazione binaria implementata, almeno vedremmo i nomi delle funzioni, come quello che vediamo nel primo backtrace 'sano'’ anteriore.

Nonostante questo, in caso di batteria rotta, l'output dei nomi delle funzioni, i nomi o i valori delle variabili non sono mai garantiti e, spesso, una verbosità è completata 🙂 Possiamo anche vedere diversi nomi di funzioni o a mucchio frantumato (un altro gergo spesso usato dagli informatici) nomi di funzioni diversi che non hanno molto senso (e probabilmente sono fittizi / false poiché lo stack è stato in qualche modo sovrascritto).

Questo rende più difficile sia per l'ingegnere di prova (che può portare a molti risultati diversi per un singolo errore, che complica la gestione del noto meccanismo di filtraggio degli errori) per quanto riguarda lo sviluppatore (che probabilmente dovrai usare una traccia passo passo o un debugger a esecuzione inversa come RR per scoprire l'errore in questione).

Cosa fare quando affronti Stack Smashing?

Se incontri batterie rotte, la prima cosa che devi fare è capire un po' meglio il problema e l'ambiente per conoscere la fonte. Se hai un server web popolare esposto su Internet con molti utenti di giochi che cercano di vincere un torneo mentre il server sta anche estraendo Bitcoin, vorrai cogliere un'opportunità di gioco scorretto e scoprire se qualcuno sta scherzando con il server.

Nonostante questo, Nella maggior parte dei casi, il problema sarà solo un errore dell'applicazione. Mentre dico 'assolo’, il problema può essere molto importante, può comportare tempi di inattività dei servizi, può costare un sacco di soldi e, finire, non si può aggiustare. Come esempio, un server di database può fallire in modo persistente quando viene avviato a causa del fatto che i dati si trovano in un determinato stato in combinazione con una carenza o limitazione nel codice.

Se tale situazione è aggravata dal non rompere la batteria, o in un altro modo, non essere in grado di generare un follow-up pulito del problema, il debug sarà più complicato e, A volte, quasi impossibile. Nonostante questo, Non preoccuparti, lo stesso debug di base di qualsiasi bug o errore / fallimento / il problema dell'applicazione rimane lo stesso.

Si prega di leggere attentamente tutti i file di registro prima, durante e dopo che si è verificato il problema. Eseguire alcuni backup e riprovare l'operazione. Fallisce di nuovo o no?? Indaga sui bug, le parti della pila e anche le cornici (In altre parole, le singole funzioni stack visualizzate, Come la do_the_maths funzione nella nostra "traccia dello stack sano"’ originale) può essere inserito nei tuoi motori di ricerca preferiti.

concatenare (con uno spazio) i frame bloccati più selettivi (superiore) e cercare lo stesso online spesso ti dà una segnalazione di bug esistente per il problema che stai affrontando. Comunque, in caso di rottura della batteria, questi fotogrammi sono probabili (nomi delle funzioni) sono stati viziati e, perché, non può più essere utilizzato allo stesso modo. Se vedi un messaggio di conferma (un'affermazione istituita dallo sviluppatore nel codice) di qualsiasi tipo, guardalo anche tu.

Invia sempre una nuova segnalazione di bug se il problema continua a non essere registrato online (Potresti aiutare gli altri che vedono lo stesso!) E fornisci quante più informazioni sul problema che puoi trovare. Ogni giorno vengono registrate online centinaia di segnalazioni di bug relative a così tante applicazioni. Auspicabilmente, il team di supporto della tua applicazione di distruzione dello stack è abilitato ad aiutarti rapidamente.

Potresti anche leggere il nostro post Debug con GDB: Introduzione qui sotto, poiché si basa su come è possibile eseguire il debug dei programmi C e C ++ (e altri) con debugger GDB. Spiega anche più in dettaglio i concetti di stack.

Iscriviti alla nostra Newsletter

Non ti invieremo posta SPAM. Lo odiamo quanto te.