core: set position earlier in smatch_flow.c
[smatch.git] / check_param_values.c
blob3c87bba38840290b75a573ceaa45db6a3e205d62
1 /*
2 * sparse/check_param_values.c
4 * Copyright (C) 2010 Dan Carpenter.
6 * Licensed under the Open Software License version 1.1
8 */
15 #include "smatch.h"
17 static int my_id;
19 STATE(user_data);
21 static void match_assign(struct expression *expr)
23 char *name;
25 name = get_macro_name(&expr->pos);
26 if (!name || strcmp(name, "get_user") != 0)
27 return;
28 name = get_variable_from_expr(expr->right, NULL);
29 if (!name || strcmp(name, "__val_gu") != 0)
30 goto free;
31 set_state_expr(my_id, expr->left, &user_data);
32 free:
33 free_string(name);
36 static void match_user_copy(const char *fn, struct expression *expr, void *_param)
38 int param = PTR_INT(_param);
39 struct expression *dest;
41 dest = get_argument_from_call_expr(expr->args, param);
42 dest = strip_expr(dest);
43 if (!dest)
44 return;
45 /* the first thing I tested this on pass &foo to a function */
46 set_state_expr(my_id, dest, &user_data);
47 if (dest->type == EXPR_PREOP && dest->op == '&') {
48 /* but normally I'd think it would pass the actual variable */
49 dest = dest->unop;
50 set_state_expr(my_id, dest, &user_data);
54 static void match_call(struct expression *expr)
56 struct expression *tmp;
57 char *func;
58 int i;
60 if (expr->fn->type != EXPR_SYMBOL)
61 return;
63 func = expr->fn->symbol_name->name;
65 i = 0;
66 FOR_EACH_PTR(expr->args, tmp) {
67 tmp = strip_expr(tmp);
68 if (get_state_expr(my_id, tmp) != &user_data) {
69 i++;
70 continue;
72 sm_msg("info: user_data %s %d", func, i);
73 i++;
74 } END_FOR_EACH_PTR(tmp);
77 void check_param_values(int id)
79 if (!option_info)
80 return;
81 if (option_project != PROJ_KERNEL)
82 return;
83 my_id = id;
84 add_hook(&match_call, FUNCTION_CALL_HOOK);
85 add_hook(&match_assign, ASSIGNMENT_HOOK);
86 add_function_hook("copy_from_user", &match_user_copy, INT_PTR(0));
87 add_function_hook("__copy_from_user", &match_user_copy, INT_PTR(0));
88 add_function_hook("memcpy_fromiovec", &match_user_copy, INT_PTR(0));
89 // memdup_user()