overflow: handle "if (strlen(foo) < 10) {..."
[smatch.git] / check_return_efault.c
blob73619c893305b96d3fb1801a8e39e3c0060915a8
1 /*
2 * smatch/check_return_efault.c
4 * Copyright (C) 2010 Dan Carpenter.
6 * Licensed under the Open Software License version 1.1
8 */
11 * This tries to find places which should probably return -EFAULT
12 * but return the number of bytes to copy instead.
15 #include "smatch.h"
16 #include "smatch_slist.h"
17 #include "smatch_extra.h"
19 static int my_id;
21 STATE(remaining);
22 STATE(ok);
24 static void ok_to_use(const char *name, struct symbol *sym, struct expression *expr, void *unused)
26 set_state(my_id, name, sym, &ok);
29 static void match_copy(const char *fn, struct expression *expr, void *unused)
31 struct expression *call;
32 struct expression *arg;
33 long long max;
35 if (expr->op == SPECIAL_SUB_ASSIGN)
36 return;
37 set_state_expr(my_id, expr->left, &remaining);
39 call = strip_expr(expr->right);
40 if (call->type != EXPR_CALL)
41 return;
42 arg = get_argument_from_call_expr(call->args, 2);
43 if (!get_absolute_max(arg, &max))
44 max = whole_range.max;
45 set_extra_expr_mod(expr->left, alloc_extra_state_range(0, max));
49 static void match_condition(struct expression *expr)
51 if (!get_state_expr(my_id, expr))
52 return;
53 /* If the variable is zero that's ok */
54 set_true_false_states_expr(my_id, expr, NULL, &ok);
58 * This function is biased in favour of print out errors.
59 * The heuristic to print is:
60 * If we have a potentially positive return from copy_to_user
61 * and there is a possibility that we return negative as well
62 * then complain.
64 static void match_return(struct expression *ret_value)
66 struct smatch_state *state;
67 struct sm_state *sm;
68 long long min;
70 sm = get_sm_state_expr(my_id, ret_value);
71 if (!sm)
72 return;
73 if (!slist_has_state(sm->possible, &remaining))
74 return;
75 state = get_state_expr(SMATCH_EXTRA, ret_value);
76 if (!state)
77 return;
78 if (!get_absolute_min(ret_value, &min))
79 return;
80 if (min == 0)
81 return;
82 sm_msg("warn: maybe return -EFAULT instead of the bytes remaining?");
85 void check_return_efault(int id)
87 if (option_project != PROJ_KERNEL)
88 return;
90 my_id = id;
91 add_function_assign_hook("copy_to_user", &match_copy, NULL);
92 add_function_assign_hook("__copy_to_user", &match_copy, NULL);
93 add_function_assign_hook("copy_from_user", &match_copy, NULL);
94 add_function_assign_hook("__copy_from_user", &match_copy, NULL);
95 add_function_assign_hook("clear_user", &match_copy, NULL);
96 add_hook(&match_condition, CONDITION_HOOK);
97 add_hook(&match_return, RETURN_HOOK);
98 set_default_modification_hook(my_id, ok_to_use);