Публикуван е експлойт за доказване на концепцията (PoC), който осигурява root достъп в OpenBSD чрез верижно използване на две уязвимости в ядрото. Основната грешка датира отпреди около 37 години още в оригиналния изходен код на BSD.
Според изследователи по сигурността от Calif уязвимостта е оцеляла, тъй като броячът за прикачване на споделена памет, наречен shm_nattch, е използвал 16-битова стойност със знак.
OpenBSD отстрани и двата проблема, преди Calif да публикува експлойта на 16 октомври 2026 г. Публикуваното изследване разглежда експлойт за локално ескалиране на привилегии и не съобщава за активно използване в реални атаки.
37-годишна уязвимост в OpenBSD
Първата уязвимост засяга обработката на споделена памет в System V. Чрез многократно разклоняване (forking) на процеси със записи за споделена памет локален потребител може да надхвърли максималната стойност на брояча от 32 767.
След това числото се превърта до отрицателна стойност. Това препълване на целочислен тип (integer overflow) може да предизвика състояние на надпревара (race condition), което води до use-after-free уязвимост в ядрото. Втора уязвимост осигурява условно записване извън границите на буфера (out-of-bounds write), давайки на изследователите достатъчен контрол, за да превърнат повреждането на паметта в root достъп.
Експлойтът на Calif мапира 127 сегмента от споделена памет, премахва техните мапирания и разклонява 259 процеса, за да принуди брояча да се превърти. След това оформя паметта в хийпа на ядрото и наблюдава данните на алокатора чрез sysctl(KERN_MALLOCSTATS).
Един процес маркира обект от споделената памет за премахване с IPC_RMID, докато помощен процес се опитва да прикачи нов сегмент в точния момент. Спечелването на тази надпревара създава заделяне в ядрото с объркан размер.
След това изследователите разполагат IP сокет обекти близо до освободената памет и използват IP_MULTICAST_TTL, за да създадат устойчив обект struct ip_moptions. Записването извън границите променя два брояча за членство в тази структура.
Затварянето на сокета задейства атомарни промени в брояча, които изменят саморефериращото се мапиране на таблицата със страници в OpenBSD. Това прави мапирането в потребителското пространство достъпно за супервайзорски режим (supervisor mode) и позволява на експлойта да презапише предвидим указател в ядрото.
След това експлойтът изпълнява код в ядрото, възстановява променения указател и отваря root шел. Веригата от уязвимости работи дори при активирани защити на OpenBSD като KARL, SMAP и SMEP, без да изисква отделно изтичане на информация. KARL променя адресите на кода и данните в ядрото при зареждане. Въпреки това от Calif установяват, че части от алокатора на памет в ядрото остават предвидими на един и същ хардуер. Обектите от ранния етап на зареждане могат да попаднат на стабилни локации, позволявайки на експлойта да таргетира указателите на ioctl манипулаторите за lo0 и enc0.
OpenBSD коригира целочисленото препълване в Errata 018 и use-after-free проблема при референтното броене в Errata 026. Страницата с корекции (errata) за OpenBSD 7.9 описва и двете решения за всички архитектури. Налични са бинарни обновления чрез syspatch за системи amd64, i386 и arm64. Администраторите трябва да инсталират всички налични корекции за сигурност и да рестартират системата, за да се зареди коригираното ядро.
От Calif предлагат и по-широкообхватни мерки за защита, включително проверки за безопасно разкачване (safe unlink) за свързани списъци, рандомизирано разполагане на мапирането на таблицата със страници и по-малко предвидими алокации в ядрото. Възможности на компилатора, като проверка на границите на масиви и изолиране на алокациите, биха затруднили експлоатирането на подобни грешки в паметта.
Изходният код на PoC е публично достъпен. Хранилището на Calif посочва разработката като част от изследователския им проект за сигурност MAD Bugs.
Случаят показва как стари архитектурни решения могат да останат скрити в надежден код на операционна система с десетилетия. Наскоро разгледахме 27-годишна уязвимост в автентикацията на OpenBSD и по-ранна уязвимост от тип double-free в OpenBSD NFS.