Wiki » History » Revision 12
« Previous |
Revision 12/14
(diff)
| Next »
Alexey Khoroshilov, 06/03/2022 12:37 PM
- Table of contents
- Статический анализ ядра
- Взаимодействие с международным сообществом
Статический анализ ядра¶
Инструкции по работе с интерфейсом разметки (SVACER) доступны в разделе файлы.
Для получения доступа к временному серверу для совместной работы над разметкой предупреждений SVACE пишите:
khoroshilov@ispras.ru
На этом сервере необходимо выбрать проект linux, ветка linux-5.10.y, в которой есть единственный снэпшот с результатами.
Для того, чтобы отфильтровать те предупреждения, которые относятся к выбранным подсистемам в режиме Review необходимо нажать на кнопку Filters->Basic...
и внизу в поле Files ввести список интересующих путей, например:
security/selinux;net/ipv4
При этом надо убедиться, что кнопка .* рядом с Files нажата. По результатам анализа
- Необходимо выставить вердикт:
- Confirmed -- ошибка, которую рекомендуется исправить
- Won't fix -- истинное срабатывание, которое по тем или иным причинам исправлять нецелесообразно
- False Positive - ложное срабатывание инструмента статического анализа
- Unclear - требуется дополнительный анализ
- На вкладке Comment необходимо оставить комментарий, поясняющий вердикт.
Сейчас это обязательно хотя бы в самом коротком виде, т.к. это единственный способ увидеть автора проведённого исследования предупреждения.
Типовые ситуации при разметке предупреждений в ядре¶
Защитное программирование¶
Например, чекеры вида UNREACHABLE_CODE.ENUM сообщают о недостижимости кода в switch для ветки по умолчанию, в которой содержится та или иная отладочная печать, например:
switch () {
case ENUM1:
...
default:
dev_dbg(ice_pf_to_dev(pf), "Invalid container type %d\n", c_type);
return -EINVAL;
}
Этот код, действительно, недостижим при нормальной работе ядра. Тем не менее, его как правило имеет смысл оставить, чтобы при возникновении нештатных ситуаций, управление пошло по более контролируемой логике и в журнале появилась информация об обнаружении нештатной ситуации.
В этом случае рекомендуется выставить вердикт Won't fix
и написать комментарий Защитное программирование
.
Недостижимый код, зависящий от конфигурации¶
Чекеры вида UNREACHABLE_CODE.* сообщают о недостижимости кода, в который, действительно, недостижим в конфигурации, которая подвержалась статическому анализу, но может быть достижим в другой конфигурации. В SVACE в будущем планируется поддержать выявление таких ситуаций и подавлять предупреждения.
До тех пор при разметке предупреждений рекомендуется выставить вердикт Won't fix
и написать комментарий Код достижим в другой конфигурации
.
FREE_OF_ARITHM: Deallocating memory through a pointer 'fl' obtained as a result of arithmetic operation¶
Срабатывают следущие чекеры: FREE_OF_ARITHM
Стандартный прием приведения члена структуры к содержащей его структуре. Используется для работы со списками, RCU, в различных видах циклов и пр. Т.к. для приведения используется макрос contaner_of, который производит арифметику, то использование такого приема вполне безопасно.
Пример:
struct ip6_flowlabel {
...
struct rcu_head rcu;
...
};
static void fl_free_rcu(struct rcu_head *head)
{
struct ip6_flowlabel *fl = container_of(head, struct ip6_flowlabel, rcu);
...
kfree(fl); // // <-- FREE_OF_ARITHM
}
static void fl_free(struct ip6_flowlabel *fl)
{
...
call_rcu(&fl->rcu, fl_free_rcu);
}
При разметке предупреждений рекомендуется выставить вердикт Won't fix
и написать комментарий Использование container_of
.
PROC_USE.VULNERABLE¶
Чаще всего возникает при использовании функции sprintf() - как правило, для нужд sysfs. Мейнтейнеры находят поведение
безопасным (sysfs использует буфер размером PAGE_SIZE) и чаще всего не принимают патчи, меняющие sprintf() на безопасные функции.
Пример:
return sprintf(buf, "%d\n", udev->rx_lanes);
Рекомендации по разметке: Won't fix/Minor/Ignore
.
VARIABLE_IS_NOT_ARRAY.PROC¶
Возникает при передаче переменной как массива (указатель и длина) при вызове функций типа of_property_read_*()
или copy_from_user()
.
Пример:
static int mmc_of_get_func_num(struct device_node *node)
{
u32 reg;
int ret;
ret = of_property_read_u32(node, "reg", ®);
if (ret < 0)
return ret;
return reg;
}
Рекомендации по разметке: False Positive/Minor/Ignore
.
UNREACHABLE_CODE.DEFAULT¶
Возникает, например, при наличии метки default
, на которую управление попасть не должно (все метки case
со значениями типа enum
перечислены явно).
Пример:
/* entry requires deletion */
case FSCACHE_CHECKAUX_OBSOLETE:
goto stale;
default:
BUG();
Рекомендации по разметке: Won't fix/Minor/Ignore
.
SIGNED_TO_BIGGER_UNSIGNED¶
Возникает при присваивании выражения знакового типа переменной беззнакового типа большей разрядности (при этом происходит sign extension
). Как правило, надо исправлять типы переменных.
Пример:
int typec_set_mode(struct typec_port *port, int mode)
{
struct typec_mux_state state = { };
state.mode = mode;
return typec_mux_set(port->mux, &state);
}
Рекомендации по разметке: Confirmed/Minor/Fix required
.
NO_CAST.INTEGER_OVERFLOW¶
Возникает при неявном преобразовании выражения к типу большей разрядности, при этом переполнения на практике обычно не происходит.
Пример:
timeout_ns = udev->u1_params.sel * 3;
Рекомендации по разметке: False Positive/Minor/Ignore
.
Взаимодействие с международным сообществом¶
Для отправки патчей в основную ветку ядра следуйте следующим инструкциям:
Отправка патчей в ядро.
Updated by Alexey Khoroshilov over 2 years ago · 14 revisions