Libseccomp: RFE: поддержка «максимальной версии ядра»

Созданный на 21 авг. 2015  ·  14Комментарии  ·  Источник: seccomp/libseccomp

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

Каноническим примером здесь является perf_event_open() , источник многочисленных CVE. Хотя производительность потрясающая, мой (например) веб-сервер не должен (по умолчанию) использовать ее.

Сегодня можно использовать seccomp для внесения в черный список. белыми списками может быть очень трудно управлять.

Одна вещь, которая может быть полезна, — это фильтр для любых системных вызовов, более новых, чем конкретная версия ядра, скажем, 3.10. Таким образом, каждый новый системный вызов должен быть проверен для использования, например, в контейнерах, прежде чем он будет добавлен. Обновление ядра не приведет к внезапному открытию контейнеров для новой поверхности атаки.

В обсуждении с @pcmoore он указал, что это может быть еще одна аннотация в структуре, например, arch-x86-syscalls.c .

enhancement pendininfo prioritmedium

Самый полезный комментарий

Похоже, проблема № 286 - это конкретная проблема, которая поможет продвинуть эту работу вперед ... даже если прошло почти пять лет ;)

Я думаю, что первым шагом к этому является добавление нового поля в файл syscalls.csv , которое указывает, когда системный вызов был впервые введен. Это будет хороший кусок работы, поскольку в настоящее время у нас определено около 469 системных вызовов (!). Однако мы могли бы амортизировать эту работу для существующих системных вызовов с «неопределенным» значением, которое мы будем рассматривать просто как системный вызов, созданный на заре времен. Конечно, все новые дополнения к таблице syscalls.csv должны быть добавлены вместе с версией ядра.

Еще несколько быстрых мыслей:

  • формат syscall.csv
#syscall (v5.8.0-rc5 2020-07-14),kver_min,x86,x86_64,...
accept,<version>,PNR,43,...

... где <version> может быть чем-то вроде "5_8", "UNDEF" или подобным.

  • токены версии
enum kernel_version {
    KV_UNDEF = 0,
    KV_1_0,
    KV_1_1,
    KV_1_3,
    KV_2_0,
    ...
    KV_5_8,
    _KV_MAX,
};

Все 14 Комментарий

+1
Это помогло бы сделать черные списки пригодными для смягчения проблем безопасности.

@nmav , чтобы быть ясным, этот RFE предназначен для добавления информации во внутренние таблицы системных вызовов о том, когда системный вызов был впервые представлен в ядре Linux, а не для добавления логики для определения того, поддерживает ли текущее работающее ядро ​​данный системный вызов. Однако, если вы пытаетесь заблокировать системный вызов, вы можете сделать это с помощью libseccomp, независимо от того, поддерживается ли он в конкретной версии Arch/ABI и ядра, libseccomp сделает все правильно за вас.

Этому RFE уже почти пять лет, и за исключением одного обсуждения с @cgwalters я не видел и не слышал о каком-либо другом интересе к такой функции. Учитывая множество других открытых вопросов, большинство из которых имеют более высокий приоритет, неясно, когда мы будем работать над этим, и даже будет ли это полезным дополнением.

@cgwalters и @drakenclimber , что вы думаете об этой проблеме в 2020 году? У меня есть соблазн закрыть это как WONTFIX, но я хотел бы получить некоторые комментарии и отзывы, прежде чем мы предпримем этот шаг.

@cgwalters и @drakenclimber , что вы думаете об этой проблеме в 2020 году? У меня есть соблазн закрыть это как WONTFIX, но я хотел бы получить некоторые комментарии и отзывы, прежде чем мы предпримем этот шаг.

Честно говоря, я думаю, что это действительно крутая идея. Несколько моих внутренних клиентов используют белые списки именно по этой причине. Если бы они использовали список запрещенных, а в ядро ​​был добавлен новый системный вызов, то этот системный вызов был бы еще одним путем атаки.

Оставим его открытым еще немного. Я поспрашиваю сотрудников Oracle и посмотрю, достаточно ли кто-нибудь из клиентов заинтересован в этой функции, чтобы я мог ее использовать. Но @cgwalters (или кто-либо другой в этом отношении) вполне может владеть им, если у них есть время и интерес :).

Хорошо, пока есть интерес, у меня нет проблем с тем, чтобы оставить это открытым.

Я все еще думаю, что это было бы полезно!

Похоже, проблема № 286 - это конкретная проблема, которая поможет продвинуть эту работу вперед ... даже если прошло почти пять лет ;)

Я думаю, что первым шагом к этому является добавление нового поля в файл syscalls.csv , которое указывает, когда системный вызов был впервые введен. Это будет хороший кусок работы, поскольку в настоящее время у нас определено около 469 системных вызовов (!). Однако мы могли бы амортизировать эту работу для существующих системных вызовов с «неопределенным» значением, которое мы будем рассматривать просто как системный вызов, созданный на заре времен. Конечно, все новые дополнения к таблице syscalls.csv должны быть добавлены вместе с версией ядра.

Еще несколько быстрых мыслей:

  • формат syscall.csv
#syscall (v5.8.0-rc5 2020-07-14),kver_min,x86,x86_64,...
accept,<version>,PNR,43,...

... где <version> может быть чем-то вроде "5_8", "UNDEF" или подобным.

  • токены версии
enum kernel_version {
    KV_UNDEF = 0,
    KV_1_0,
    KV_1_1,
    KV_1_3,
    KV_2_0,
    ...
    KV_5_8,
    _KV_MAX,
};

Версию ядра нужно отслеживать? Гарантируется ли, что более новые системные вызовы не переносятся, например, в стабильные ветки ядра с более низким номером версии?

Red Hat будет переносить все что угодно в свои ядра, так что нет.

Если RedHat переносит системный вызов на более старую версию ядра, они также могут исправить свою версию libseccomp, чтобы она соответствовала. Хотя, если честно, это может иметь большее значение для определенных случаев использования, но как подход к исправлению # 286 я думаю, что это вполне работоспособно. Другая проблема заключается в том, что я не уверен, что есть лучший подход — системные вызовы могут быть добавлены в непоследовательном порядке (например, openat2 был добавлен до close_range — хотя этот пример любезен). по моей вине).

Если RedHat переносит системный вызов на более старую версию ядра, они также могут исправить свою версию libseccomp, чтобы она соответствовала.

Да, точно. Вышестоящий проект libseccomp не имеет контроля над различными корпоративными дистрибутивами Linux, и если эти дистрибутивы решат отклониться от исходных проектов (будь то ядро ​​Linux или libseccomp), они будут самостоятельно получать поддержку. Хотя мы сделаем все возможное, чтобы помочь, мы не можем пожертвовать исходным проектом в пользу этих корпоративных дистрибутивов с их собственной поддержкой и инженерным персоналом.

Для справки, на справочной странице syscalls(2) есть некоторая историческая информация о том, когда в ядро ​​были введены различные системные вызовы:

Я могу провести анализ системных вызовов, чтобы выяснить номер версии для каждого системного вызова — единственный вопрос заключается в том, должны ли мы иметь номер версии для каждой архитектуры, поскольку я почти уверен, что определенные системные вызовы были добавлены к разным архитектурам в разных выпусках.

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

Они определенно были и остаются, насколько я могу судить. Хотя это будет немного раздражать и определенно взорвет CSV, отслеживание первого появления системного вызова для каждой арки/ABI, вероятно, будет правильным решением.

Мы будем очень признательны за любую помощь, которую вы можете оказать в этом @cyphar .

Была ли эта страница полезной?
0 / 5 - 0 рейтинги