La versione in fase di sviluppo del kernel Linux 5.12 include l'implementazione del meccanismo KFence (Kernel Electric Fence), che verifica l'uso della memoria catturando i limiti superati dei buffer, gli accessi alla memoria dopo il rilascio e altri errori simili.
Una funzionalità simile era già presente nel kernel come opzione di compilazione KASAN (kernel address sanitizer, utilizza Address Sanitizer nelle moderne gcc e clang) — tuttavia, era principalmente posizionata per impieghi di debug. La sottosistema KFence si distingue da KASAN per l'alta velocità di esecuzione, il che consente di utilizzare questa capacità anche nei kernel di sistemi operativi in produzione.
L'applicazione nei sistemi operativi in produzione permetterà di catturare errori nella gestione della memoria che non si manifestano nei test e che emergono solo sotto carichi di lavoro o durante lunghi periodi di funzionamento (con un alto uptime). Inoltre, l'uso di KFence nei sistemi operativi attivi consentirà di aumentare significativamente il numero di macchine coinvolte nel controllo della gestione della memoria del kernel.
KFence raggiunge le spese generali minime, indipendenti dal carico, grazie all'inserimento delle pagine di protezione (guard pages) nella memoria heap a intervalli fissi. Una volta scaduto il tempo dell'intervallo di protezione, KFence aggiunge una nuova pagina di protezione dal pool di oggetti KFence attraverso il sistema di allocazione della memoria standard (SLAB o SLUB allocator) e inizia un nuovo conteggio del timer. Ogni oggetto KFence viene allocato in una pagina di memoria separata, e le pagine di memoria ai bordi sinistro e destro formano le pagine di protezione, la cui dimensione viene scelta casualmente.
In questo modo, le pagine con oggetti sono separate l'una dall'altra da pagine di protezione, che sono configurate per generare un "page fault" ad ogni accesso. Per rilevare le operazioni di scrittura oltre il limite del buffer all'interno delle pagine con oggetti vengono utilizzate ulteriori "zone rosse" basate su modelli, che occupano memoria non utilizzata dagli oggetti, risultante nell'allineamento delle dimensioni delle pagine di memoria. —+————+————+————+————+————+— | xxxxxxxxx | O : | xxxxxxxxx | : O | xxxxxxxxx | | xxxxxxxxx | B : | xxxxxxxxx | : B | xxxxxxxxx | | x GUARD x | J : RED- | x GUARD x | RED- : J | x GUARD x | | xxxxxxxxx | E : ZONE | xxxxxxxxx | ZONE : E | xxxxxxxxx | | xxxxxxxxx | C : | xxxxxxxxx | : C | xxxxxxxxx | | xxxxxxxxx | T : | xxxxxxxxx | : T | xxxxxxxxx | —+————+————+————+————+————+—
In caso di tentativo di accesso a un'area al di fuori dei limiti del buffer, l'operazione colpisce la pagina di protezione, il che porta alla generazione di un "page fault", che viene intercettato da KFence e contabilizza nel log i dati sul problema rilevato. Per impostazione predefinita, KFence non blocca l'errore e semplicemente genera un avviso nel log, ma è prevista un'impostazione "panic_on_warn", che consente di portare il kernel in uno stato di crash (panic) in caso di errore rilevato.
Fonte: opennet.ru
