Защита Linux с помощью функций усиления ядра

Новые функции защиты ядра могут защитить от ошибок, которые чаще всего используются злоумышленниками, даже если ошибка еще не обнаружена.

Задача защиты систем Linux настолько ошеломляюще сложна и включает в себя так много уровней технологий, что она может легко ошеломить разработчиков.
Тем не менее, есть несколько довольно простых средств защиты, которые вы можете использовать в самом ядре: ядро.
Эти методы защиты помогают разработчикам защититься от ошибок, которые еще не были обнаружены.

«Усиление заключается в том, чтобы сделать ошибки более трудными для использования», - объяснил Марк Ратланд, разработчик ядра в ARM Ltd, на недавней конференции Embedded Linux Conference Europe 2016 в Берлине.
Он всегда добавляет, что всегда будут опасные ошибки, которые могут ускользнуть от внимания разработчиков ядра.
«Мы еще не знаем, какие именно ошибки существуют в следующем ядре, и мы, вероятно, не будем в течение пяти лет», - сказал он, ссылаясь на недавний анализ Kees Cook недавнего времени жизни ошибок ядра.


Марк Ратленд рассказывает об усилении ядра Linux на ELCE 2016

(щелкните изображение, чтобы увеличить)

«Мы видим повторяющиеся классы ошибок, связанных с такими вещами, как разыменование нулевых указателей или доступ к памяти, контролируемой пользовательским пространством, поэтому мы можем предположить, что некоторые из ошибок, о которых мы не знаем, попадут в эти корзины».

Ратленд, который ранее в этом году предупредил участников ELC North America о скрытых опасностях недисциплинированных кешей , отметил, что ошибки являются неизбежным следствием программирования.
Большинство из них относительно доброкачественные, но многие вызывают проблемы, а некоторые могут открыть опасные уязвимости.

«В окне слияния в ядре 4.8 мы исправили более 500 ошибок, многие из которых были в 4.7 или более ранних», - сказал Ратленд, отметив, что, хотя сегодня используются разные методы, чтобы избежать попадания ошибок в ядро, некоторые из них неизбежно проскальзывают и требуют позже исправления.
Это «немного страшно», учитывая долгий срок службы ошибок, которые могут не быть обнаружены до тех пор, пока поврежденные устройства не закончат работу.

Некоторые из этих ошибок имеют значительные последствия для безопасности.
К счастью, разработчики ядра в последние годы начали создавать функции защиты, которые защищают от многих наиболее распространенных ошибок.
Ратленд умолял аудиторию использовать эти защитные функции, отметив, что многие из них просты для включения, а их средства защиты «эффективно бесплатны», но не видят широкого применения.

Ратленд продолжил обсуждение нескольких основных классов защитных ограждений, которые представляют наименьшее количество накладных расходов.
Вот некоторые отредактированные цитаты о каждом:

Строгие разрешения памяти ядра - «Исторически ядро ​​отображало всю память как читаемую, записываемую и исполняемую… что приводит к… возможности изменять код ядра или постоянные данные или выполнять данные, которые все… являются очень полезными примитивами, если вы злоумышленник
Мы можем заставить MMU принудительно реализовать эти разрешения,… отображая этот код как доступный только для чтения или отображая постоянные данные только для чтения и неисполняемые.
Если это сделано в MMU, оно фактически бесплатное, поскольку аппаратное обеспечение обрабатывает его для нас ». (Для получения дополнительной информации изучите CONFIG_DEBUG_RODATA и CONFIG_DEBUG_SET-MODULE_RONX.)

Защита с разбивкой стека - «Атаки с разбивкой стека работают по принципу, согласно которому стеки содержат адрес возврата и другие данные, а также локальные переменные.
На большинстве архитектур стек растет вниз, а буферы - вверх.
Если вы копируете некоторые данные в буфер в стеке, и эти данные слишком велики, чтобы поместиться в буфер, вы в конечном итоге перезаписываете последующие данные, в которые входит адрес возврата.
Поэтому, если злоумышленник знает, как будет выглядеть макет фрейма стека, он может контролировать, куда вы вернетесь, и… переходить к любому коду по своему выбору… для запуска более сложных атак.
Защита от стека, защищающая от этого, заставляет компилятор вставлять секретное значение, известное как канарейка, между данными и информацией управления потоком ». (Подробности см. В разделах CONFIG_STACKPROTECTOR_REGULAR и CONFIG_STACKPROTECTOR_STRONG.)

Разделение памяти между пользователем и ядром - «Обычно ядро ​​разделяет адресное пространство с пространством пользователя в аппаратном обеспечении.
Указатель может закодировать адрес в любом месте ... используя те же инструкции загрузки и сохранения.
Если вы случайно разыменовали адрес… контролируемый пространством пользователя, аппаратное обеспечение не заметит и с радостью предоставит вам значение, поэтому, если злоумышленник сможет убедить вас разыменовать адрес… его можно использовать в качестве основы для ряда атак. ,
Если злоумышленник помещает буфер кода в адрес пространства пользователя, а затем использует эксплойт для разрушения стека, он может сделать все, что захочет.
MMU может помочь, позволяя нам динамически изменять таблицу страниц, которую мы используем для переключения процессов.
Временное включение доступа, а затем отключение доступа… перехватит большинство этих непреднамеренных обращений к памяти пользователя или ответвлений ».

Более строгие разрешения - «Некоторое оборудование может… автоматически предотвращать выполнение произвольного кода из буфера пространства пользователя.
В ARM у нас есть функция, называемая привилегией выполнить никогда (PXN), которая ... говорит, что я никогда не хочу, чтобы эта страница выполнялась с привилегиями ядра.
В x86 есть похожая вещь под названием SMEP.
Злоумышленник по-прежнему может переходить к другому фрагменту кода ядра, поэтому он не предотвращает произвольное выполнение, но ограничивает один случай.
Совсем недавно MMU стали способны делать это и с доступом к данным ».

Ратленд сообщил, что пройдет «годы, прежде чем у нас будет разумное количество мер защиты». Он также отметил, что средства защиты не являются стопроцентно эффективными, и что «нам все еще нужно находить и исправлять ошибки».

По мнению Ратленда, системы Linux были бы более безопасными, если бы по умолчанию было включено больше этих функций защиты, что, по его словам, произошло в ядре 4.9 с обязательным, упомянутым выше DEBUG_RODATA.
«Сопротивление постепенно исчезает для некоторых из этих средств защиты», - сказал он.
«Многие жалобы на то, что функции не похожи на код ядра и делают что-то неправильно, решаются довольно быстро.
Мнения людей о магистрали меняются - есть согласие, что да, нам нужно что-то здесь делать ».

Посмотрите полное видео презентации Ратленда «Устранение неизвестных ошибок: усиление функций основного ядра Linux» ниже:

«Предотвращение неизвестных ошибок: усиление функций основного ядра Linux»

Эта статья защищена авторским правом © 2016 Linux.com и была первоначально опубликована здесь .
Он был воспроизведен этим сайтом с разрешения его владельца.
Пожалуйста, посетите Linux.com для получения последних новостей и статей о Linux и open source.