static void print_error_description(struct kasan_access_info *info) { const char *bug_type = "unknown-crash"; u8 *shadow_addr; info->first_bad_addr = find_first_bad_addr(info->access_addr, info->access_size); shadow_addr = (u8 *)kasan_mem_to_shadow(info->first_bad_addr); /* * If shadow byte value is in [0, KASAN_SHADOW_SCALE_SIZE) we can look * at the next shadow byte to determine the type of the bad access. */ if (*shadow_addr > 0 && *shadow_addr <= KASAN_SHADOW_SCALE_SIZE - 1) shadow_addr++; switch (*shadow_addr) { case 0 ... KASAN_SHADOW_SCALE_SIZE - 1: /* * In theory it's still possible to see these shadow values * due to a data race in the kernel code. */ bug_type = "out-of-bounds"; break; case KASAN_PAGE_REDZONE: case KASAN_KMALLOC_REDZONE: bug_type = "slab-out-of-bounds"; break; case KASAN_GLOBAL_REDZONE: bug_type = "global-out-of-bounds"; break; case KASAN_STACK_LEFT: case KASAN_STACK_MID: case KASAN_STACK_RIGHT: case KASAN_STACK_PARTIAL: bug_type = "stack-out-of-bounds"; break; case KASAN_FREE_PAGE: case KASAN_KMALLOC_FREE: bug_type = "use-after-free"; break; case KASAN_USE_AFTER_SCOPE: bug_type = "use-after-scope"; break; } pr_err("BUG: KASAN: %s in %pS at addr %p\n", bug_type, (void *)info->ip, info->access_addr); pr_err("%s of size %zu by task %s/%d\n", info->is_write ? "Write" : "Read", info->access_size, current->comm, task_pid_nr(current)); }
static const char *get_shadow_bug_type(struct kasan_access_info *info) { const char *bug_type = "unknown-crash"; u8 *shadow_addr; info->first_bad_addr = find_first_bad_addr(info->access_addr, info->access_size); shadow_addr = (u8 *)kasan_mem_to_shadow(info->first_bad_addr); /* * If shadow byte value is in [0, KASAN_SHADOW_SCALE_SIZE) we can look * at the next shadow byte to determine the type of the bad access. */ if (*shadow_addr > 0 && *shadow_addr <= KASAN_SHADOW_SCALE_SIZE - 1) shadow_addr++; switch (*shadow_addr) { case 0 ... KASAN_SHADOW_SCALE_SIZE - 1: /* * In theory it's still possible to see these shadow values * due to a data race in the kernel code. */ bug_type = "out-of-bounds"; break; case KASAN_PAGE_REDZONE: case KASAN_KMALLOC_REDZONE: bug_type = "slab-out-of-bounds"; break; case KASAN_GLOBAL_REDZONE: bug_type = "global-out-of-bounds"; break; case KASAN_STACK_LEFT: case KASAN_STACK_MID: case KASAN_STACK_RIGHT: case KASAN_STACK_PARTIAL: bug_type = "stack-out-of-bounds"; break; case KASAN_FREE_PAGE: case KASAN_KMALLOC_FREE: bug_type = "use-after-free"; break; case KASAN_USE_AFTER_SCOPE: bug_type = "use-after-scope"; break; case KASAN_ALLOCA_LEFT: case KASAN_ALLOCA_RIGHT: bug_type = "alloca-out-of-bounds"; break; } return bug_type; }
static void print_error_description(struct kasan_access_info *info) { const char *bug_type = "unknown crash"; u8 shadow_val; info->first_bad_addr = find_first_bad_addr(info->access_addr, info->access_size); shadow_val = *(u8 *)kasan_mem_to_shadow(info->first_bad_addr); switch (shadow_val) { case KASAN_FREE_PAGE: case KASAN_KMALLOC_FREE: bug_type = "use after free"; break; case KASAN_PAGE_REDZONE: case KASAN_KMALLOC_REDZONE: case KASAN_GLOBAL_REDZONE: case 0 ... KASAN_SHADOW_SCALE_SIZE - 1: bug_type = "out of bounds access"; break; case KASAN_STACK_LEFT: case KASAN_STACK_MID: case KASAN_STACK_RIGHT: case KASAN_STACK_PARTIAL: bug_type = "out of bounds on stack"; break; } pr_err("BUG: KASan: %s in %pS at addr %p\n", bug_type, (void *)info->ip, info->access_addr); pr_err("%s of size %zu by task %s/%d\n", info->is_write ? "Write" : "Read", info->access_size, current->comm, task_pid_nr(current)); }