points_to_user_data: add xdr_copy_to_scratch()
[smatch.git] / check_kernel.c
blob7b17a37b103494154918623970b7e2bc1e2b954e
1 /*
2 * Copyright (C) 2010 Dan Carpenter.
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version 2
7 * of the License, or (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, see http://www.gnu.org/copyleft/gpl.txt
19 * This is kernel specific stuff for smatch_extra.
22 #include "scope.h"
23 #include "smatch.h"
24 #include "smatch_slist.h"
25 #include "smatch_extra.h"
27 static int implied_err_cast_return(struct expression *call, void *unused, struct range_list **rl)
29 struct expression *arg;
31 arg = get_argument_from_call_expr(call->args, 0);
32 if (!get_implied_rl(arg, rl))
33 return false;
35 *rl = cast_rl(get_type(call), *rl);
36 return !!*rl;
39 static void hack_ERR_PTR(struct symbol *sym)
41 struct symbol *arg;
42 struct smatch_state *estate;
43 struct range_list *after;
44 sval_t low_error = {
45 .type = &long_ctype,
46 .value = -4095,
48 sval_t minus_one = {
49 .type = &long_ctype,
50 .value = -1,
52 sval_t zero = {
53 .type = &long_ctype,
54 .value = 0,
57 if (!sym || !sym->ident)
58 return;
59 if (strcmp(sym->ident->name, "ERR_PTR") != 0)
60 return;
62 arg = first_ptr_list((struct ptr_list *)sym->ctype.base_type->arguments);
63 if (!arg || !arg->ident)
64 return;
66 estate = get_state(SMATCH_EXTRA, arg->ident->name, arg);
67 if (!estate) {
68 after = alloc_rl(low_error, minus_one);
69 } else {
70 after = rl_intersection(estate_rl(estate), alloc_rl(low_error, zero));
71 if (rl_equiv(estate_rl(estate), after))
72 return;
74 set_state(SMATCH_EXTRA, arg->ident->name, arg, alloc_estate_rl(after));
77 static void match_param_valid_ptr(const char *fn, struct expression *call_expr,
78 struct expression *assign_expr, void *_param)
80 int param = PTR_INT(_param);
81 struct expression *arg;
82 struct smatch_state *pre_state;
83 struct smatch_state *end_state;
84 struct range_list *rl;
86 arg = get_argument_from_call_expr(call_expr->args, param);
87 pre_state = get_state_expr(SMATCH_EXTRA, arg);
88 if (estate_rl(pre_state)) {
89 rl = estate_rl(pre_state);
90 rl = remove_range(rl, ptr_null, ptr_null);
91 rl = remove_range(rl, ptr_err_min, ptr_err_max);
92 } else {
93 rl = alloc_rl(valid_ptr_min_sval, valid_ptr_max_sval);
95 end_state = alloc_estate_rl(rl);
96 set_extra_expr_nomod(arg, end_state);
99 static void match_param_err_or_null(const char *fn, struct expression *call_expr,
100 struct expression *assign_expr, void *_param)
102 int param = PTR_INT(_param);
103 struct expression *arg;
104 struct range_list *pre, *rl;
105 struct smatch_state *pre_state;
106 struct smatch_state *end_state;
108 arg = get_argument_from_call_expr(call_expr->args, param);
109 pre_state = get_state_expr(SMATCH_EXTRA, arg);
110 if (pre_state)
111 pre = estate_rl(pre_state);
112 else
113 pre = alloc_whole_rl(&ptr_ctype);
114 call_results_to_rl(call_expr, &ptr_ctype, "0,(-4095)-(-1)", &rl);
115 rl = rl_intersection(pre, rl);
116 rl = cast_rl(get_type(arg), rl);
117 end_state = alloc_estate_rl(rl);
118 set_extra_expr_nomod(arg, end_state);
121 static void match_not_err(const char *fn, struct expression *call_expr,
122 struct expression *assign_expr, void *unused)
124 struct expression *arg;
125 struct smatch_state *pre_state;
126 struct range_list *rl;
128 arg = get_argument_from_call_expr(call_expr->args, 0);
129 pre_state = get_state_expr(SMATCH_EXTRA, arg);
130 if (pre_state) {
131 rl = estate_rl(pre_state);
132 rl = remove_range(rl, ptr_err_min, ptr_err_max);
133 } else {
134 rl = alloc_rl(valid_ptr_min_sval, valid_ptr_max_sval);
136 rl = cast_rl(get_type(arg), rl);
137 set_extra_expr_nomod(arg, alloc_estate_rl(rl));
140 static void match_err(const char *fn, struct expression *call_expr,
141 struct expression *assign_expr, void *unused)
143 struct expression *arg;
144 struct smatch_state *pre_state;
145 struct range_list *rl;
147 arg = get_argument_from_call_expr(call_expr->args, 0);
148 pre_state = get_state_expr(SMATCH_EXTRA, arg);
149 rl = estate_rl(pre_state);
150 if (!rl)
151 rl = alloc_rl(ptr_err_min, ptr_err_max);
152 rl = rl_intersection(rl, alloc_rl(ptr_err_min, ptr_err_max));
153 rl = cast_rl(get_type(arg), rl);
154 set_extra_expr_nomod(arg, alloc_estate_rl(rl));
157 static void match_container_of_macro(const char *fn, struct expression *expr, void *unused)
159 set_extra_expr_mod(expr->left, alloc_estate_range(valid_ptr_min_sval, valid_ptr_max_sval));
162 static void match_container_of(struct expression *expr)
164 struct expression *right = expr->right;
165 char *macro;
168 * The problem here is that sometimes the container_of() macro is itself
169 * inside a macro and get_macro() only returns the name of the outside
170 * macro.
174 * This actually an expression statement assignment but smatch_flow
175 * pre-mangles it for us so we only get the last chunk:
176 * sk = (typeof(sk))((char *)__mptr - offsetof(...))
179 macro = get_macro_name(right->pos);
180 if (!macro)
181 return;
182 if (right->type != EXPR_CAST)
183 return;
184 right = strip_expr(right);
185 if (right->type != EXPR_BINOP || right->op != '-' ||
186 right->left->type != EXPR_CAST)
187 return;
188 right = strip_expr(right->left);
189 if (right->type != EXPR_SYMBOL)
190 return;
191 if (!right->symbol->ident ||
192 strcmp(right->symbol->ident->name, "__mptr") != 0)
193 return;
194 set_extra_expr_mod(expr->left, alloc_estate_range(valid_ptr_min_sval, valid_ptr_max_sval));
197 static int match_next_bit(struct expression *call, void *unused, struct range_list **rl)
199 struct expression *start_arg;
200 struct expression *size_arg;
201 struct symbol *type;
202 sval_t min, max, tmp;
204 size_arg = get_argument_from_call_expr(call->args, 1);
205 /* btw. there isn't a start_arg for find_first_bit() */
206 start_arg = get_argument_from_call_expr(call->args, 2);
208 type = get_type(call);
209 min = sval_type_val(type, 0);
210 max = sval_type_val(type, sizeof(long long) * 8);
212 if (get_implied_max(size_arg, &tmp) && tmp.uvalue < max.value)
213 max = tmp;
214 if (start_arg && get_implied_min(start_arg, &tmp) && !sval_is_negative(tmp))
215 min = tmp;
216 if (sval_cmp(min, max) > 0)
217 max = min;
218 min = sval_cast(type, min);
219 max = sval_cast(type, max);
220 *rl = alloc_rl(min, max);
221 return 1;
224 static int match_array_size(struct expression *call, void *unused, struct range_list **rl)
226 struct expression *size;
227 struct expression *count;
228 struct expression *mult;
229 struct range_list *ret;
231 size = get_argument_from_call_expr(call->args, 0);
232 count = get_argument_from_call_expr(call->args, 1);
233 mult = binop_expression(size, '*', count);
235 if (get_implied_rl(mult, &ret)) {
236 *rl = ret;
237 return 1;
240 return 0;
243 static int match_ffs(struct expression *call, void *unused, struct range_list **rl)
245 if (get_implied_rl(call, rl))
246 return true;
247 return false;
250 static int match_fls(struct expression *call, void *unused, struct range_list **rl)
252 struct expression *arg;
253 struct range_list *arg_rl;
254 sval_t zero = {};
255 sval_t start = {
256 .type = &int_ctype,
257 .value = 0,
259 sval_t end = {
260 .type = &int_ctype,
261 .value = 32,
263 sval_t sval;
265 arg = get_argument_from_call_expr(call->args, 0);
266 if (!get_implied_rl(arg, &arg_rl))
267 return 0;
268 if (rl_to_sval(arg_rl, &sval)) {
269 int i;
271 for (i = 63; i >= 0; i--) {
272 if (sval.uvalue & 1ULL << i)
273 break;
275 sval.value = i + 1;
276 *rl = alloc_rl(sval, sval);
277 return 1;
279 zero.type = rl_type(arg_rl);
280 if (!rl_has_sval(arg_rl, zero))
281 start.value = 1;
282 *rl = alloc_rl(start, end);
283 return 1;
286 static void find_module_init_exit(struct symbol_list *sym_list)
288 struct symbol *sym;
289 struct symbol *fn;
290 struct statement *stmt;
291 char *name;
292 int init;
293 int count;
296 * This is more complicated because Sparse ignores the "alias"
297 * attribute. I search backwards because module_init() is normally at
298 * the end of the file.
300 count = 0;
301 FOR_EACH_PTR_REVERSE(sym_list, sym) {
302 if (sym->type != SYM_NODE)
303 continue;
304 if (!(sym->ctype.modifiers & MOD_STATIC))
305 continue;
306 fn = get_base_type(sym);
307 if (!fn)
308 continue;
309 if (fn->type != SYM_FN)
310 continue;
311 if (!sym->ident)
312 continue;
313 if (!fn->inline_stmt)
314 continue;
315 if (strcmp(sym->ident->name, "__inittest") == 0)
316 init = 1;
317 else if (strcmp(sym->ident->name, "__exittest") == 0)
318 init = 0;
319 else
320 continue;
322 count++;
324 stmt = first_ptr_list((struct ptr_list *)fn->inline_stmt->stmts);
325 if (!stmt || stmt->type != STMT_RETURN)
326 continue;
327 name = expr_to_var(stmt->ret_value);
328 if (!name)
329 continue;
330 if (init)
331 sql_insert_function_ptr(name, "(struct module)->init");
332 else
333 sql_insert_function_ptr(name, "(struct module)->exit");
334 free_string(name);
335 if (count >= 2)
336 return;
337 } END_FOR_EACH_PTR_REVERSE(sym);
340 static void match_end_file(struct symbol_list *sym_list)
342 struct symbol *sym;
344 /* find the last static symbol in the file */
345 FOR_EACH_PTR_REVERSE(sym_list, sym) {
346 if (!(sym->ctype.modifiers & MOD_STATIC))
347 continue;
348 if (!sym->scope)
349 continue;
350 find_module_init_exit(sym->scope->symbols);
351 return;
352 } END_FOR_EACH_PTR_REVERSE(sym);
355 static struct expression *get_val_expr(struct expression *expr)
357 struct symbol *sym, *val;
359 if (expr->type != EXPR_DEREF)
360 return NULL;
361 expr = expr->deref;
362 if (expr->type != EXPR_SYMBOL)
363 return NULL;
364 if (strcmp(expr->symbol_name->name, "__u") != 0)
365 return NULL;
366 sym = get_base_type(expr->symbol);
367 val = first_ptr_list((struct ptr_list *)sym->symbol_list);
368 if (!val || strcmp(val->ident->name, "__val") != 0)
369 return NULL;
370 return member_expression(expr, '.', val->ident);
373 static void match__write_once_size(const char *fn, struct expression *call,
374 void *unused)
376 struct expression *dest, *data, *assign;
377 struct range_list *rl;
379 dest = get_argument_from_call_expr(call->args, 0);
380 if (dest->type != EXPR_PREOP || dest->op != '&')
381 return;
382 dest = strip_expr(dest->unop);
384 data = get_argument_from_call_expr(call->args, 1);
385 data = get_val_expr(data);
386 if (!data)
387 return;
388 get_absolute_rl(data, &rl);
389 assign = assign_expression(dest, '=', data);
391 __in_fake_assign++;
392 __split_expr(assign);
393 __in_fake_assign--;
396 static void match__read_once_size(const char *fn, struct expression *call,
397 void *unused)
399 struct expression *dest, *data, *assign;
400 struct symbol *type, *val_sym;
403 * We want to change:
404 * __read_once_size_nocheck(&(x), __u.__c, sizeof(x));
405 * into a fake assignment:
406 * __u.val = x;
410 data = get_argument_from_call_expr(call->args, 0);
411 if (data->type != EXPR_PREOP || data->op != '&')
412 return;
413 data = strip_parens(data->unop);
415 dest = get_argument_from_call_expr(call->args, 1);
416 if (dest->type != EXPR_DEREF || dest->op != '.')
417 return;
418 if (!dest->member || strcmp(dest->member->name, "__c") != 0)
419 return;
420 dest = dest->deref;
421 type = get_type(dest);
422 if (!type)
423 return;
424 val_sym = first_ptr_list((struct ptr_list *)type->symbol_list);
425 dest = member_expression(dest, '.', val_sym->ident);
427 assign = assign_expression(dest, '=', data);
428 __in_fake_assign++;
429 __split_expr(assign);
430 __in_fake_assign--;
433 static void match_closure_call(const char *name, struct expression *call,
434 void *unused)
436 struct expression *cl, *fn, *fake_call;
437 struct expression_list *args = NULL;
439 cl = get_argument_from_call_expr(call->args, 0);
440 fn = get_argument_from_call_expr(call->args, 1);
441 if (!fn || !cl)
442 return;
444 add_ptr_list(&args, cl);
445 fake_call = call_expression(fn, args);
446 __split_expr(fake_call);
449 static bool has_inc_state(const char *name, struct symbol *sym)
451 static int refcount_id;
452 struct sm_state *sm, *tmp;
454 if (!refcount_id)
455 refcount_id = id_from_name("check_refcount_info");
457 sm = get_sm_state(refcount_id, name, sym);
458 if (!sm)
459 return false;
461 FOR_EACH_PTR(sm->possible, tmp) {
462 if (strcmp(tmp->state->name, "inc") == 0)
463 return true;
465 * &ignore counts as an inc, because that's what happens when
466 * you double increment. Not ideal.
468 if (strcmp(tmp->state->name, "ignore") == 0)
469 return true;
470 } END_FOR_EACH_PTR(tmp);
472 return false;
475 static void match_kref_put(const char *fn, struct expression *call_expr,
476 struct expression *expr, void *_unused)
478 struct expression *data, *release, *fake_call;
479 struct expression_list *args = NULL;
480 struct symbol *sym;
481 char *ref;
484 if (call_expr->type != EXPR_CALL)
485 return;
487 data = get_argument_from_call_expr(call_expr->args, 0);
489 ref = get_name_sym_from_param_key(call_expr, 0, "$->refcount.refs.counter", &sym);
490 if (has_inc_state(ref, sym))
491 return;
493 release = get_argument_from_call_expr(call_expr->args, 1);
495 add_ptr_list(&args, data);
496 fake_call = call_expression(release, args);
497 add_fake_call_after_return(fake_call);
500 static void match_kernel_param(struct symbol *sym)
502 struct expression *var;
503 struct symbol *type;
505 /* This was designed to parse the module_param_named() macro */
507 if (!sym->ident ||
508 !sym->initializer ||
509 sym->initializer->type != EXPR_INITIALIZER)
510 return;
512 type = get_real_base_type(sym);
513 if (!type || type->type != SYM_STRUCT || !type->ident)
514 return;
515 if (strcmp(type->ident->name, "kernel_param") != 0)
516 return;
518 var = last_ptr_list((struct ptr_list *)sym->initializer->expr_list);
519 if (!var || var->type != EXPR_INITIALIZER)
520 return;
521 var = first_ptr_list((struct ptr_list *)var->expr_list);
522 if (!var || var->type != EXPR_PREOP || var->op != '&')
523 return;
524 var = strip_expr(var->unop);
526 type = get_type(var);
527 update_mtag_data(var, alloc_estate_whole(type));
530 bool is_ignored_kernel_data(const char *name)
532 char *p;
534 if (option_project != PROJ_KERNEL)
535 return false;
538 * On the file I was looking at lockdep was 25% of the DB.
540 if (strstr(name, ".dep_map."))
541 return true;
542 if (strstr(name, "->dep_map."))
543 return true;
544 if (strstr(name, ".lockdep_map."))
545 return true;
547 if (strstr(name, ".rwsem."))
548 return true;
549 if (strstr(name, "->rwsem."))
550 return true;
552 if (strstr(name, "->mutex."))
553 return true;
554 if (strstr(name, "->lockdep_mutex."))
555 return true;
557 if (strstr(name, ".completion.wait."))
558 return true;
560 if (strstr(name, "kobj.kset-"))
561 return true;
562 if (strstr(name, "power.suspend_timer."))
563 return true;
564 if (strstr(name, "power.work."))
565 return true;
566 if (strstr(name, ".lock.rlock."))
567 return true;
568 if (strstr(name, "lockdep_mutex."))
569 return true;
571 if (strstr(name, ">klist_devices."))
572 return true;
574 if (strstr(name, "->m_log->"))
575 return true;
577 if (strstr(name, ".wait_lock."))
578 return true;
579 if (strstr(name, "regmap->lock_arg"))
580 return true;
581 if (strstr(name, "kworker->task"))
582 return true;
583 if (strstr(name, "->algo_data->"))
584 return true;
586 /* ignore mutex internals */
587 if ((p = strstr(name, ".rlock.")) ||
588 (p = strstr(name, ">rlock."))) {
589 p += 7;
590 if (strncmp(p, "raw_lock", 8) == 0 ||
591 strcmp(p, "owner") == 0 ||
592 strcmp(p, "owner_cpu") == 0 ||
593 strcmp(p, "magic") == 0 ||
594 strcmp(p, "dep_map") == 0)
595 return true;
598 return false;
601 int get_gfp_param(struct expression *expr)
603 struct symbol *type;
604 struct symbol *arg, *arg_type;
605 int param;
607 if (expr->type != EXPR_CALL)
608 return -1;
609 type = get_type(expr->fn);
610 if (!type)
611 return -1;
612 if (type->type == SYM_PTR)
613 type = get_real_base_type(type);
614 if (type->type != SYM_FN)
615 return -1;
617 param = 0;
618 FOR_EACH_PTR(type->arguments, arg) {
619 arg_type = get_base_type(arg);
620 if (arg_type && arg_type->ident &&
621 strcmp(arg_type->ident->name, "gfp_t") == 0)
622 return param;
623 param++;
624 } END_FOR_EACH_PTR(arg);
626 return -1;
629 static void match_function_def(struct symbol *sym)
631 char *macro;
633 macro = get_macro_name(sym->pos);
634 if (!macro)
635 return;
636 if (strcmp(macro, "TRACE_EVENT") == 0)
637 set_function_skipped();
640 static bool delete_pci_error_returns(struct expression *expr)
642 const char *macro;
643 sval_t sval;
645 if (!get_value(expr, &sval))
646 return false;
647 if (sval.value < 0x80 || sval.value > 0x90)
648 return false;
650 macro = get_macro_name(expr->pos);
651 if (!macro)
652 return false;
654 if (strncmp(macro, "PCIBIOS_", 8) != 0)
655 return false;
657 if (strcmp(macro, "PCIBIOS_FUNC_NOT_SUPPORTED") == 0 ||
658 strcmp(macro, "PCIBIOS_BAD_VENDOR_ID") == 0 ||
659 strcmp(macro, "PCIBIOS_DEVICE_NOT_FOUND") == 0 ||
660 strcmp(macro, "PCIBIOS_BAD_REGISTER_NUMBER") == 0 ||
661 strcmp(macro, "PCIBIOS_SET_FAILED") == 0 ||
662 strcmp(macro, "PCIBIOS_BUFFER_TOO_SMALL") == 0)
663 return true;
665 return false;
668 static bool match_with_intel_runtime(struct statement *stmt)
670 char *macro;
672 macro = get_macro_name(stmt->pos);
673 if (!macro)
674 return false;
675 if (strncmp(macro, "with_intel_runtime", 18) == 0)
676 return true;
677 return false;
680 void check_kernel(int id)
682 if (option_project != PROJ_KERNEL)
683 return;
685 add_implied_return_hook("ERR_PTR", &implied_err_cast_return, NULL);
686 add_implied_return_hook("ERR_CAST", &implied_err_cast_return, NULL);
687 add_implied_return_hook("PTR_ERR", &implied_err_cast_return, NULL);
688 add_hook(hack_ERR_PTR, AFTER_DEF_HOOK);
689 return_implies_state("IS_ERR_OR_NULL", 0, 0, &match_param_valid_ptr, (void *)0);
690 return_implies_state("IS_ERR_OR_NULL", 1, 1, &match_param_err_or_null, (void *)0);
691 return_implies_state("IS_ERR", 0, 0, &match_not_err, NULL);
692 return_implies_state("IS_ERR", 1, 1, &match_err, NULL);
693 return_implies_state("tomoyo_memory_ok", 1, 1, &match_param_valid_ptr, (void *)0);
695 add_macro_assign_hook_extra("container_of", &match_container_of_macro, NULL);
696 add_hook(match_container_of, ASSIGNMENT_HOOK);
698 add_implied_return_hook("find_next_bit", &match_next_bit, NULL);
699 add_implied_return_hook("find_next_zero_bit", &match_next_bit, NULL);
700 add_implied_return_hook("find_first_bit", &match_next_bit, NULL);
701 add_implied_return_hook("find_first_zero_bit", &match_next_bit, NULL);
703 add_implied_return_hook("array_size", &match_array_size, NULL);
705 add_implied_return_hook("__ffs", &match_ffs, NULL);
706 add_implied_return_hook("fls", &match_fls, NULL);
707 add_implied_return_hook("__fls", &match_fls, NULL);
708 add_implied_return_hook("fls64", &match_fls, NULL);
710 add_function_hook("__ftrace_bad_type", &__match_nullify_path_hook, NULL);
711 add_function_hook("__write_once_size", &match__write_once_size, NULL);
713 add_function_hook("__read_once_size", &match__read_once_size, NULL);
714 add_function_hook("__read_once_size_nocheck", &match__read_once_size, NULL);
716 add_function_hook("closure_call", &match_closure_call, NULL);
717 return_implies_state_sval("kref_put", int_one, int_one, &match_kref_put, NULL);
719 add_once_through_hook(&match_with_intel_runtime);
721 add_hook(&match_kernel_param, BASE_HOOK);
722 add_hook(&match_function_def, FUNC_DEF_HOOK);
724 if (option_info)
725 add_hook(match_end_file, END_FILE_HOOK);
727 add_delete_return_hook(&delete_pci_error_returns);