Project

General

Profile

Wiki » History » Version 14

Alexey Khoroshilov, 08/23/2022 08:41 PM

1 7 Alexey Khoroshilov
{{toc}}
2
3 4 Alexey Khoroshilov
h2. Статический анализ ядра
4
5 5 Alexey Khoroshilov
Инструкции по работе с интерфейсом разметки (SVACER) доступны в разделе "файлы":https://forge.ispras.ru/projects/lvc/files.
6
7
8 4 Alexey Khoroshilov
Для получения доступа к временному серверу для совместной работы над разметкой предупреждений SVACE пишите:
9
khoroshilov@ispras.ru
10
11 5 Alexey Khoroshilov
На этом сервере необходимо выбрать проект linux, ветка linux-5.10.y, в которой есть единственный снэпшот с результатами.
12
13
Для того, чтобы отфильтровать те предупреждения, которые относятся к выбранным подсистемам в режиме Review необходимо нажать на кнопку Filters->Basic...
14
и внизу в поле Files ввести список интересующих путей, например:
15
<pre>
16
security/selinux;net/ipv4
17
</pre>
18
При этом надо убедиться, что кнопка .* рядом с Files нажата.
19
20
По результатам анализа 
21
# Необходимо выставить вердикт:
22 14 Alexey Khoroshilov
** @Confirmed@ -- ошибка, которую рекомендуется исправить
23
** @Won't fix@ -- истинное срабатывание, которое по тем или иным причинам исправлять нецелесообразно
24
** @False Positive@ - ложное срабатывание инструмента статического анализа
25
** @Unclear@ - требуется дополнительный анализ
26
# На вкладке @Comment@ необходимо оставить комментарий, поясняющий вердикт.
27 7 Alexey Khoroshilov
28
h3. Типовые ситуации при разметке предупреждений в ядре
29
30
h4. Защитное программирование
31
32 14 Alexey Khoroshilov
Как пример, детекторы вида @UNREACHABLE_CODE.ENUM@ или @UNREACHABLE_CODE.DEFAULT@ сообщают о недостижимости кода в @switch@ для ветки по умолчанию, в которой содержится та или иная отладочная печать. Например:
33 7 Alexey Khoroshilov
34
<pre><code class="c">
35
  switch () {
36
  case ENUM1:
37 1 Alexey Khoroshilov
  ...
38
  default:
39
    dev_dbg(ice_pf_to_dev(pf), "Invalid container type %d\n", c_type);
40 7 Alexey Khoroshilov
    return -EINVAL;
41
  }
42
</code></pre>
43 1 Alexey Khoroshilov
44 14 Alexey Khoroshilov
Этот код, действительно, недостижим при нормальной работе ядра. Тем не менее, его, как правило, имеет смысл оставить, чтобы при возникновении нештатных ситуаций, управление пошло по более контролируемой логике, и в журнале появилась информация об обнаружении нештатной ситуации.
45 7 Alexey Khoroshilov
46 14 Alexey Khoroshilov
Аналогичная ситуация возникает в детекторах вида @UNREACHABLE_CODE@ при вызове функций, которые всегда возвращают @0@. Тем не менее, для многих из них можно предположить, что реализация со временем может измениться, и функция начнёт возвращать код ошибки. Поэтому обработку кода ошибки можно оставить на будущее.
47
48 1 Alexey Khoroshilov
В этом случае рекомендуется выставить вердикт @Won't fix@ и написать комментарий @Защитное программирование@.
49 7 Alexey Khoroshilov
50 8 Alexey Khoroshilov
h4. Недостижимый код, зависящий от конфигурации
51
52 14 Alexey Khoroshilov
Детекторы вида @UNREACHABLE_CODE.*@ сообщают о недостижимости кода, который, действительно, недостижим в конфигурации, которая подвергалась статическому анализу, но может быть достижим в другой конфигурации. В SVACE в будущем планируется поддержать выявление таких ситуаций и подавлять такие предупреждения.
53 8 Alexey Khoroshilov
54
До тех пор при разметке предупреждений рекомендуется выставить вердикт @Won't fix@ и написать комментарий @Код достижим в другой конфигурации@.
55 5 Alexey Khoroshilov
56 14 Alexey Khoroshilov
h4. @FREE_OF_ARITHM: Deallocating memory through a pointer 'fl' obtained as a result of arithmetic operation@ 
57 9 Елена Кузьмина
58 14 Alexey Khoroshilov
Срабатывают следущие детекторы: @FREE_OF_ARITHM@.
59 9 Елена Кузьмина
60 14 Alexey Khoroshilov
Стандартный прием приведения члена структуры к содержащей его структуре. Используется для работы со списками, RCU, в различных видах циклов и пр. Так как для приведения используется макрос @container_of@, который производит арифметику, то использование такого приема вполне безопасно.
61 10 Alexey Khoroshilov
62 9 Елена Кузьмина
Пример:
63
<pre><code class="c">
64
struct ip6_flowlabel {
65
	...
66
	struct rcu_head		rcu;
67
	...
68
};
69
70
static void fl_free_rcu(struct rcu_head *head)
71
{
72
	struct ip6_flowlabel *fl = container_of(head, struct ip6_flowlabel, rcu);
73 1 Alexey Khoroshilov
        ...
74
	kfree(fl);  // // <-- FREE_OF_ARITHM
75 9 Елена Кузьмина
}
76
77
static void fl_free(struct ip6_flowlabel *fl)
78
{
79
        ...
80
	call_rcu(&fl->rcu, fl_free_rcu);
81
}
82 1 Alexey Khoroshilov
</code></pre>
83 10 Alexey Khoroshilov
84
При разметке предупреждений рекомендуется выставить вердикт @Won't fix@ и написать комментарий @Использование container_of@.
85 9 Елена Кузьмина
86 14 Alexey Khoroshilov
h4. @PROC_USE.VULNERABLE@
87 11 Елена Кузьмина
88 14 Alexey Khoroshilov
Чаще всего возникает при использовании функции @sprintf()@, как правило, для нужд @sysfs@. Мейнтейнеры находят поведение
89
безопасным (@sysfs@ использует буфер размером @PAGE_SIZE@) и чаще всего не принимают патчи, меняющие @sprintf()@ на безопасные функции.
90 11 Елена Кузьмина
91
Пример:
92
<pre><code class="c">
93
return sprintf(buf, "%d\n", udev->rx_lanes);
94
</code></pre>
95
96
Рекомендации по разметке: @Won't fix/Minor/Ignore@ .
97
98 14 Alexey Khoroshilov
h4. @VARIABLE_IS_NOT_ARRAY.PROC@
99 11 Елена Кузьмина
100
Возникает при передаче переменной как массива (указатель и длина) при вызове функций типа @of_property_read_*()@ или @copy_from_user()@.
101
102 1 Alexey Khoroshilov
Пример:
103 11 Елена Кузьмина
<pre><code class="c">
104
static int mmc_of_get_func_num(struct device_node *node)
105
{
106
	u32 reg;
107
	int ret;
108
109 1 Alexey Khoroshilov
	ret = of_property_read_u32(node, "reg", &reg);
110 11 Елена Кузьмина
	if (ret < 0)
111 1 Alexey Khoroshilov
		return ret;
112 11 Елена Кузьмина
	return reg;
113 1 Alexey Khoroshilov
}
114 11 Елена Кузьмина
</code></pre>
115
116
Рекомендации по разметке: @False Positive@ .
117
118
119 14 Alexey Khoroshilov
h4. @SIGNED_TO_BIGGER_UNSIGNED@
120 11 Елена Кузьмина
121
Возникает при присваивании выражения знакового типа переменной беззнакового типа большей разрядности (при этом происходит @sign extension@). Как правило, надо исправлять типы переменных.
122
123
Пример:
124
<pre><code class="c">
125
int typec_set_mode(struct typec_port *port, int mode)
126
{
127
	struct typec_mux_state state = { };
128
	state.mode = mode;
129
	return typec_mux_set(port->mux, &state);
130
}
131
</code></pre>
132
133
Рекомендации по разметке: @Confirmed/Minor/Fix required@ .
134
135
h4. NO_CAST.INTEGER_OVERFLOW
136
137 12 Alexey Khoroshilov
Возникает при неявном преобразовании выражения к типу большей разрядности, при этом переполнения на практике обычно не происходит.
138 11 Елена Кузьмина
Пример:
139
<pre><code class="c">
140
timeout_ns = udev->u1_params.sel * 3;
141
</code></pre>
142 1 Alexey Khoroshilov
143 14 Alexey Khoroshilov
Рекомендации по разметке: @False Positive@.
144 13 Елена Кузьмина
145 14 Alexey Khoroshilov
h4. @DEREF_AFTER_FREE: A pointer to memory pointer that has been deallocated, is dereferenced@
146 13 Елена Кузьмина
147 14 Alexey Khoroshilov
Срабатывают следущие детекторы: @DEREF_AFTER_FREE@.
148 13 Елена Кузьмина
149
Стандартный прием безопасного удаления элемента списка при обходе. Для этого используется макрос 
150 1 Alexey Khoroshilov
<pre><code class="c">
151
list_for_each_entry_safe():
152
153
#define list_for_each_entry_safe(pos, n, head, member)			\
154
	for (pos = list_first_entry(head, typeof(*pos), member),	\
155
		n = list_next_entry(pos, member);			\
156
	     !list_entry_is_head(pos, head, member); 			\
157
	     pos = n, n = list_next_entry(n, member))
158
</code></pre>
159
160
Пример:
161
<pre><code class="c">
162
static void serio_free_event(struct serio_event *event)
163
{
164
	module_put(event->owner);
165
	kfree(event);
166
}
167
168
static void serio_remove_pending_events(void *object)
169
{
170
	struct serio_event *event, *next;
171
	unsigned long flags;
172
173
	spin_lock_irqsave(&serio_event_lock, flags);
174
175
	list_for_each_entry_safe(event, next, &serio_event_list, node) {  // <-- DEREF_AFTER_FREE
176
177
		if (event->object == object) {
178
			list_del_init(&event->node); // Элемент удаляется из списка
179 13 Елена Кузьмина
			serio_free_event(event);     // Освобождается память, но next элемент отстается! В конце цикла происходит инициализация event = next;
180
		}
181
	}
182
183
	spin_unlock_irqrestore(&serio_event_lock, flags);
184
}
185
</code></pre>
186
187 14 Alexey Khoroshilov
Рекомендации по разметке: @False Positive@.
188
189
h4. @SIZEOF_POINTER_TYPE@
190
191
Данный тип детектора предназначен для обнаружения несоответствий в конструкциях вида @x = (T1*)alloc(sizeof(T2))@, когда тип передаваемый в оператор @sizeof()@ не соответствует по размеру типу, к которому приводится результирующий указатель. Если инструмент обнаруживает похожую конструкцию, которая используется не для выделения памяти, то предупреждение будет ошибочным.
192
193
Например при использовании макроса:
194
<pre><code class="c">
195
#define cmpxchg(ptr, ...)						\
196
({									\
197
	typeof(ptr) __ai_ptr = (ptr);					\
198
	instrument_atomic_write(__ai_ptr, sizeof(*__ai_ptr));		\
199
	arch_cmpxchg(__ai_ptr, __VA_ARGS__);				\
200
})
201
#endif
202
</code></pre>
203
204
где arch_cmpxchg в свою очередь расширяется в:
205
<pre><code class="c">
206
#define __cmpxchg_wrapper(sfx, ptr, o, n)				\
207
({									\
208
	__typeof__(*(ptr)) __ret;					\
209
	__ret = (__typeof__(*(ptr)))					\
210
		__cmpxchg##sfx((ptr), (unsigned long)(o),		\
211
				(unsigned long)(n), sizeof(*(ptr)));	\
212
	__ret;								\
213
})
214
</code></pre>
215
216
Рекомендации по разметке: @False Positive@.
217 11 Елена Кузьмина
218 4 Alexey Khoroshilov
h2. Взаимодействие с международным сообществом
219 1 Alexey Khoroshilov
220 6 Alexey Khoroshilov
Для отправки патчей в основную ветку ядра следуйте следующим инструкциям:
221
[[How_to_send_patches_to_kernel|Отправка патчей в ядро]].