В разработеното ядро на Linux 5.12 е внедрена реализация на механизма KFence (Kernel Electric Fence), който следи работата с паметта, улавяйки изтичания извън границите на буферите, достъпи до паметта след освобождаване и други подобни грешки.
Тази функционалност вече съществуваше в ядрото като опция за компилиране KASAN (kernel address sanitizer, използваща Address Sanitizer в съвременните gcc и clang) — но основно бе предназначена за отстраняване на грешки. Подсистемата KFence се отличава от KASAN с високата си производителност, което позволява използването на тази възможност дори в ядра на работещи системи.
Приложението в работещи системи ще позволи улавянето на грешки в работата с паметта, които не се проявяват при тестови изпълнения и зачекват само при натоварвания или продължителна работа (с голям uptime). Освен това, прилагането на KFence в работещи системи ще увеличи значително броя на машините, участващи в проверката на работата на ядрото с паметта.
Минималните разходи, независещи от натоварването, се постигат в KFence благодарение на вмъкването на защитни страници (guard pages) в купчината с фиксирани интервали. След като приключи времето на текущия защитен интервал, KFence чрез стандартната система за разпределение на паметта (SLAB или SLUB allocator) добавя нова защитна страница от пула на обектите KFence и започва новото отчета на времето. Всеки обект KFence се разполага на отделна страница памет, а страниците памет отляво и отдясно образуват защитни страници (guard pages), чиито размери се избират на случаен принцип.
Така страниците с обекти са разделени една от друга с защитни страници, които са настроени да генерират «page fault» при всяко достъпване. За откриване на операции по запис извън границите на буфера в страниците с обекти освен това се използват «червени зони» на основата на шаблони, които заемат памет, не използвана от обектите и оставаща след подравняване на размера на страниците памет. —+————+————+————+————+————+— | 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 | —+————+————+————+————+————+—
Ако се опита да се получи достъп до област извън границите на буфера, операцията засяга защитната страница, което води до генериране на "page fault", който KFence улавя и регистрира информация за открития проблем. По подразбиране KFence не блокира грешката и просто извежда предупреждение в логовете, но е предвидена конфигурация "panic_on_warn", която позволява, ако бъде открита грешка, ядрото да бъде преведено в състояние на срив (panic).
Източник: opennet.ru
