1 #include "smatch.h" 2 #include "linearize.h" 3 4 static int my_id; 5 static struct symbol *cur_syscall; 6 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 44 static inline void prefix() { 45 printf("%s:%d %s() ", get_filename(), get_lineno(), get_function()); 46 } 47 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 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 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 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 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 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