1#include "smatch.h"
2#include "linearize.h"
3
4static int my_id;
5static struct symbol *cur_syscall;
6
7static const char *expression_type_name(enum expression_type type)
8{
9	static const char *expression_type_name[] = {
10		[EXPR_VALUE] = "EXPR_VALUE",
11		[EXPR_STRING] = "EXPR_STRING",
12		[EXPR_SYMBOL] = "EXPR_SYMBOL",
13		[EXPR_TYPE] = "EXPR_TYPE",
14		[EXPR_BINOP] = "EXPR_BINOP",
15		[EXPR_ASSIGNMENT] = "EXPR_ASSIGNMENT",
16		[EXPR_LOGICAL] = "EXPR_LOGICAL",
17		[EXPR_DEREF] = "EXPR_DEREF",
18		[EXPR_PREOP] = "EXPR_PREOP",
19		[EXPR_POSTOP] = "EXPR_POSTOP",
20		[EXPR_CAST] = "EXPR_CAST",
21		[EXPR_FORCE_CAST] = "EXPR_FORCE_CAST",
22		[EXPR_IMPLIED_CAST] = "EXPR_IMPLIED_CAST",
23		[EXPR_SIZEOF] = "EXPR_SIZEOF",
24		[EXPR_ALIGNOF] = "EXPR_ALIGNOF",
25		[EXPR_PTRSIZEOF] = "EXPR_PTRSIZEOF",
26		[EXPR_CONDITIONAL] = "EXPR_CONDITIONAL",
27		[EXPR_SELECT] = "EXPR_SELECT",
28		[EXPR_STATEMENT] = "EXPR_STATEMENT",
29		[EXPR_CALL] = "EXPR_CALL",
30		[EXPR_COMMA] = "EXPR_COMMA",
31		[EXPR_COMPARE] = "EXPR_COMPARE",
32		[EXPR_LABEL] = "EXPR_LABEL",
33		[EXPR_INITIALIZER] = "EXPR_INITIALIZER",
34		[EXPR_IDENTIFIER] = "EXPR_IDENTIFIER",
35		[EXPR_INDEX] = "EXPR_INDEX",
36		[EXPR_POS] = "EXPR_POS",
37		[EXPR_FVALUE] = "EXPR_FVALUE",
38		[EXPR_SLICE] = "EXPR_SLICE",
39		[EXPR_OFFSETOF] = "EXPR_OFFSETOF",
40	};
41	return expression_type_name[type] ?: "UNKNOWN_EXPRESSION_TYPE";
42}
43
44static inline void prefix() {
45	printf("%s:%d %s() ", get_filename(), get_lineno(), get_function());
46}
47
48static void match_syscall_definition(struct symbol *sym)
49{
50	// struct symbol *arg;
51	char *macro;
52	char *name;
53	int is_syscall = 0;
54
55	macro = get_macro_name(sym->pos);
56	if (macro &&
57	    (strncmp("SYSCALL_DEFINE", macro, strlen("SYSCALL_DEFINE")) == 0 ||
58	     strncmp("COMPAT_SYSCALL_DEFINE", macro, strlen("COMPAT_SYSCALL_DEFINE")) == 0))
59		is_syscall = 1;
60
61	name = get_function();
62
63	/*
64	if (!option_no_db && get_state(my_id, "this_function", NULL) != &called) {
65		if (name && strncmp(name, "sys_", 4) == 0)
66			is_syscall = 1;
67	}
68	*/
69
70	/* Ignore compat_sys b/c syzkaller doesn't fuzz these?
71	if (name && strncmp(name, "compat_sys_", 11) == 0)
72		is_syscall = 1;
73	*/
74
75	if (!is_syscall)
76		return;
77	printf("-------------------------\n");
78	printf("\nsyscall found: %s at: ", name);
79	prefix(); printf("\n");
80	cur_syscall = sym;
81
82	/*
83	FOR_EACH_PTR(sym->ctype.base_type->arguments, arg) {
84		set_state(my_id, arg->ident->name, arg, &user_data_set);
85	} END_FOR_EACH_PTR(arg);
86	*/
87}
88
89static void match_after_syscall(struct symbol *sym) {
90    if (cur_syscall && sym == cur_syscall) {
91	printf("\n"); prefix();
92	printf("exiting scope of syscall %s\n", get_function());
93	printf("-------------------------\n");
94	cur_syscall = NULL;
95    }
96}
97
98static void print_member_type(struct expression *expr)
99{
100	char *member;
101
102	member = get_member_name(expr);
103	if (!member)
104		return;
105	// sm_msg("info: uses %s", member);
106	prefix();
107	printf("info: uses %s\n", member);
108	free_string(member);
109}
110
111static void match_condition(struct expression *expr) {
112    if (!cur_syscall)
113	return;
114
115    /*
116    prefix();
117    printf("found conditional %s on line %d\n", expression_type_name(expr->type), get_lineno());
118    printf("expr_str: %s\n", expr_to_str(expr));
119    */
120
121    /*
122    switch (expr->type) {
123	case EXPR_COMPARE:
124	    match_condition(expr->left);
125	    match_condition(expr->right);
126	    break;
127	case EXPR_SYMBOL:
128	    printf("symbol: %s\n", expr->symbol_name->name);
129	    break;
130	case EXPR_CALL:
131	    break;
132    }
133    */
134
135    prefix(); printf("-- condition found\n");
136
137    if (expr->type == EXPR_COMPARE || expr->type == EXPR_BINOP
138	    || expr->type == EXPR_LOGICAL
139	    || expr->type == EXPR_ASSIGNMENT
140	    || expr->type == EXPR_COMMA) {
141	    match_condition(expr->left);
142	    match_condition(expr->right);
143	    return;
144    }
145    print_member_type(expr);
146
147}
148
149static void match_function_call(struct expression *expr) {
150    if (!cur_syscall)
151	return;
152    prefix();
153    printf("function call %s\n", expression_type_name(expr->type));
154}
155
156void check_implicit_dependencies_tester(int id)
157{
158    my_id = id;
159
160    if (option_project != PROJ_KERNEL)
161	return;
162
163    add_hook(&match_syscall_definition, AFTER_DEF_HOOK);
164    add_hook(&match_after_syscall, AFTER_FUNC_HOOK);
165    add_hook(&match_condition, CONDITION_HOOK);
166    add_hook(&match_function_call, FUNCTION_CALL_HOOK);
167}
168
169