Esempio n. 1
0
static void match_dev_put(const char *fn, struct expression *expr, void *data)
{
	struct expression *arg_expr;

	arg_expr = get_argument_from_call_expr(expr->args, 0);
	set_state_expr(my_id, arg_expr, &released);
}
Esempio n. 2
0
static void match_dma_func(const char *fn, struct expression *expr, void *param)
{
	struct expression *arg;
	struct symbol *sym;
	char *name;

	arg = get_argument_from_call_expr(expr->args, PTR_INT(param));
	arg = strip_expr(arg);
	if (!arg)
		return;
	if (arg->type == EXPR_PREOP && arg->op == '&') {
		if (arg->unop->type != EXPR_SYMBOL)
			return;
		name = expr_to_str(arg);
		sm_msg("error: doing dma on the stack (%s)", name);
		free_string(name);
		return;
	}
	if (arg->type != EXPR_SYMBOL)
		return;
	sym = get_type(arg);
	if (!sym || sym->type != SYM_ARRAY)
		return;
	name = expr_to_var(arg);
	sm_msg("error: doing dma on the stack (%s)", name);
	free_string(name);
}
Esempio n. 3
0
static int param_caps_return(struct expression *call, void *_arg, struct range_list **res)
{
	int arg = PTR_INT(_arg);
	struct expression *expr;
	struct range_list *rl;

	expr = get_argument_from_call_expr(call->args, arg);
	if (get_implied_rl(expr, &rl) && rl_max(rl).value != 0)
		*res = alloc_rl(sval_type_val(rl_type(rl), 0), rl_max(rl));
	return 1;
}
Esempio n. 4
0
static void match_capable(const char *fn, struct expression *expr, void *_param)
{
	struct expression *arg;
	sval_t sval;
	char buf[32];

	arg = get_argument_from_call_expr(expr->args, 0);
	if (!get_implied_value(arg, &sval))
		return;
	snprintf(buf, sizeof(buf), "%s", sval_to_str(sval));
	set_state(capable_id, buf, NULL, &capable);
}
Esempio n. 5
0
static void match_strcpy(const char *fn, struct expression *expr, void *unused)
{
	struct expression *dest;
	struct expression *data;
	char *dest_name = NULL;
	char *data_name = NULL;
	int dest_size;
	int data_size;

	dest = get_argument_from_call_expr(expr->args, 0);
	data = get_argument_from_call_expr(expr->args, 1);
	dest_size = get_array_size_bytes(dest);
	if (!dest_size)
		return;

	data_size = get_size_from_strlen(data);
	if (!data_size)
		data_size = get_array_size_bytes(data);

	/* If the size of both arrays is known and the destination
	 * buffer is larger than the source buffer, we're okay.
	 */
	if (data_size && dest_size >= data_size)
		return;

	dest_name = expr_to_str(dest);
	data_name = expr_to_str(data);

	if (data_size)
		sm_msg("error: %s() '%s' too large for '%s' (%d vs %d)",
			fn, data_name, dest_name, data_size, dest_size);
	else if (option_spammy)
		sm_msg("warn: %s() '%s' of unknown size might be too large for '%s'",
			fn, data_name, dest_name);

	free_string(dest_name);
	free_string(data_name);
}
Esempio n. 6
0
static void match_calloc(const char *fn, struct expression *expr, void *_arg_nr)
{
	int arg_nr = PTR_INT(_arg_nr);
	struct expression *call = strip_expr(expr->right);
	struct expression *arg;
	int ptr_size;

	ptr_size = get_data_size(expr->left);
	if (!ptr_size)
		return;

	arg = get_argument_from_call_expr(call->args, arg_nr);
	check_size_matches(ptr_size, arg);
}
Esempio n. 7
0
static void match_free(const char *fn, struct expression *expr, void *data)
{
	struct expression *arg_expr;
	char *name;
	sval_t sval;

	arg_expr = get_argument_from_call_expr(expr->args, 0);
	if (!get_implied_value(arg_expr, &sval))
		return;
	if (sval.value != 0)
		return;
	name = expr_to_var(arg_expr);
	sm_msg("warn: calling %s() when '%s' is always NULL.", fn, name);
	free_string(name);
}
Esempio n. 8
0
static void match_resource(const char *fn, struct expression *expr, void *_arg_no)
{
	struct expression *arg_expr;
	int arg_no = PTR_INT(_arg_no);

	arg_expr = get_argument_from_call_expr(expr->args, arg_no);
	arg_expr = strip_expr(arg_expr);
	if (!arg_expr)
		return;

	if (arg_expr->type == EXPR_SYMBOL) {
		handle_assigned_expr(arg_expr);
		return;
	}
	verify_size_expr(arg_expr);
}
Esempio n. 9
0
static void match_call(const char *fn, struct expression *expr, void *_arg_no)
{
	struct expression *arg_expr;
	int arg_no = PTR_INT(_arg_no);
	sval_t sval;
	char *name;

	arg_expr = get_argument_from_call_expr(expr->args, arg_no);
	if (positions_eq(expr->pos, arg_expr->pos))
		return;
	name = pos_ident(arg_expr->pos);
	if (!name)
		return;
	if (!get_value(arg_expr, &sval))
		return;
	sm_msg("info: bit shifter '%s' '%s'", name, sval_to_str(sval));
}
Esempio n. 10
0
static void match_alloc(const char *fn, struct expression *expr, void *unused)
{
	struct expression *call = strip_expr(expr->right);
	struct expression *arg;
	int ptr_size;

	ptr_size = get_data_size(expr->left);
	if (!ptr_size)
		return;

	arg = get_argument_from_call_expr(call->args, 0);
	arg = strip_expr(arg);
	if (!arg || arg->type != EXPR_BINOP || arg->op != '*')
		return;
	if (expr->left->type == EXPR_SIZEOF)
		check_size_matches(ptr_size, arg->left);
	if (expr->right->type == EXPR_SIZEOF)
		check_size_matches(ptr_size, arg->right);
}
Esempio n. 11
0
static int match_strlen(struct expression *call, void *unused, struct range_list **rl)
{
	struct expression *str;
	unsigned long max;

	str = get_argument_from_call_expr(call->args, 0);
	if (get_implied_strlen(str, rl) && sval_is_positive(rl_min(*rl))) {
		*rl = cast_rl(&ulong_ctype, *rl);
		return 1;
	}
	/* smatch_strlen.c is not very complete */
	max = get_array_size_bytes_max(str);
	if (max == 0) {
		*rl = alloc_rl(sval_type_val(&ulong_ctype, 0),
			       sval_type_val(&ulong_ctype, STRLEN_MAX_RET));
	} else {
		max--;
		*rl = alloc_rl(sval_type_val(&ulong_ctype, 0),
			       sval_type_val(&ulong_ctype, max));
	}
	return 1;
}
Esempio n. 12
0
static void db_param_cleared(struct expression *expr, int param, char *key, char *value)
{
	struct expression *arg;

	while (expr->type == EXPR_ASSIGNMENT)
		expr = strip_expr(expr->right);
	if (expr->type != EXPR_CALL)
		return;

	arg = get_argument_from_call_expr(expr->args, param);
	arg = strip_expr(arg);
	if (!arg)
		return;
	if (arg->type != EXPR_SYMBOL)
		return;
	if (get_param_num_from_sym(arg->symbol) < 0)
		return;

	if (strcmp(value, "0") == 0)
		set_state_expr(my_id, arg, &zeroed);
	else
		set_state_expr(my_id, arg, &cleared);
}
Esempio n. 13
0
static int match_strnlen(struct expression *call, void *unused, struct range_list **rl)
{
	struct expression *limit;
	sval_t fixed;
	sval_t bound;
	sval_t ulong_max = sval_type_val(&ulong_ctype, ULONG_MAX);

	match_strlen(call, NULL, rl);
	limit = get_argument_from_call_expr(call->args, 1);
	if (!get_implied_max(limit, &bound))
		return 1;
	if (sval_cmp(bound, ulong_max) == 0)
		return 1;
	if (rl_to_sval(*rl, &fixed) && sval_cmp(fixed, bound) >= 0) {
		*rl = alloc_rl(bound, bound);
		return 1;
	}

	bound.value++;
	*rl = remove_range(*rl, bound, ulong_max);

	return 1;
}