1 #include "smatch.h"
2 #include "linearize.h"
3 
4 static int my_id;
5 static struct symbol *cur_syscall;
6 
expression_type_name(enum expression_type type)7 static 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 
prefix()44 static inline void prefix() {
45 	printf("%s:%d %s() ", get_filename(), get_lineno(), get_function());
46 }
47 
match_syscall_definition(struct symbol * sym)48 static 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 
match_after_syscall(struct symbol * sym)89 static 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 
print_member_type(struct expression * expr)98 static 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 
match_condition(struct expression * expr)111 static 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 
match_function_call(struct expression * expr)149 static 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 
check_implicit_dependencies_tester(int id)156 void 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