GNU/Linux >> Linux Esercitazione >  >> Linux

Cosa imposta fs:[0x28] (stack canary)?

È facile tenere traccia di questa inizializzazione, come per (quasi) ogni processo strace mostra una chiamata di sistema molto sospetta durante l'inizio dell'esecuzione del processo:

arch_prctl(ARCH_SET_FS, 0x7fc189ed0740) = 0

Questo è ciò che man 2 arch_prctl dice:

   ARCH_SET_FS
          Set the 64-bit base for the FS register to addr.

Sì, sembra proprio quello di cui abbiamo bisogno. Per trovare, chi chiama arch_prctl , cerchiamo un backtrace:

(gdb) catch syscall arch_prctl
Catchpoint 1 (syscall 'arch_prctl' [158])
(gdb) r
Starting program: <program path>

Catchpoint 1 (call to syscall arch_prctl), 0x00007ffff7dd9cad in init_tls () from /lib64/ld-linux-x86-64.so.2
(gdb) bt
#0  0x00007ffff7dd9cad in init_tls () from /lib64/ld-linux-x86-64.so.2
#1  0x00007ffff7ddd3e3 in dl_main () from /lib64/ld-linux-x86-64.so.2
#2  0x00007ffff7df04c0 in _dl_sysdep_start () from /lib64/ld-linux-x86-64.so.2
#3  0x00007ffff7dda028 in _dl_start () from /lib64/ld-linux-x86-64.so.2
#4  0x00007ffff7dd8fb8 in _start () from /lib64/ld-linux-x86-64.so.2
#5  0x0000000000000001 in ?? ()
#6  0x00007fffffffecef in ?? ()
#7  0x0000000000000000 in ?? ()

Quindi, la base del segmento FS è impostata dal ld-linux , che fa parte di glibc , durante il caricamento del programma (se il programma è collegato staticamente, questo codice è incorporato nel binario). Qui è dove tutto accade.

Durante l'avvio, il caricatore inizializza TLS. Ciò include l'allocazione della memoria e l'impostazione del valore di base FS in modo che punti all'inizio di TLS. Questo viene fatto tramite arch_prctl syscall. Dopo l'inizializzazione TLS security_init viene chiamata la funzione, che genera il valore della protezione dello stack e lo scrive nella posizione di memoria, quale fs:[0x28] punta a:

  • Inizializzazione del valore di protezione dello stack
  • Scrittura del valore di protezione dello stack, più dettagliata

E 0x28 è l'offset del stack_guard campo nella struttura che si trova all'inizio di TLS.


Quello che vedi è chiamato (in GCC) Stack Smashing Protector (SSP), che è una forma di protezione dall'overflow del buffer generata dal compilatore. Il valore è un numero casuale generato dal programma all'avvio e, come menziona l'articolo di Wikipedia, viene inserito in Thread Local Storage (TLS). Altri compilatori possono utilizzare strategie diverse per implementare questo tipo di protezione.

Perché archiviare il valore in TLS? Poiché il valore si trova lì, il suo indirizzo non è accessibile dai registri CS, DS e SS, rendendo molto difficile indovinare il valore memorizzato se stai tentando di alterare lo stack da codice dannoso.


Linux
  1. Che cos'è un utente Linux?

  2. Cosa significa il valore del simbolo dal comando nm?

  3. Cosa fa ulimit -s illimitato?

  4. Stampa il valore del puntatore dello stack

  5. Qual è il valore di JAVA_HOME per CentOS?

Cos'è lo stack LAMP?

Cos'è SSH?

Cos'è l'SFTP?

Cosa significa null in Linux e nell'informatica

Cosa sta arrivando in GNOME 42?

Cos'è l'analfabetismo digitale?