@@ -156,6 +156,8 @@ struct kasan_report_info {
/* Filled in by the common reporting code. */
void *first_bad_addr;
+ struct kmem_cache *cache;
+ void *object;
};
/* Do not change the struct layout: compiler ABI. */
@@ -281,19 +281,16 @@ static inline bool init_task_stack_addr(const void *addr)
sizeof(init_thread_union.stack));
}
-static void print_address_description(void *addr, u8 tag)
+static void print_address_description(void *addr, u8 tag,
+ struct kasan_report_info *info)
{
struct page *page = addr_to_page(addr);
- struct slab *slab = kasan_addr_to_slab(addr);
dump_stack_lvl(KERN_ERR);
pr_err("\n");
- if (slab) {
- struct kmem_cache *cache = slab->slab_cache;
- void *object = nearest_obj(cache, slab, addr);
-
- describe_object(cache, object, addr, tag);
+ if (info->cache && info->object) {
+ describe_object(info->cache, info->object, addr, tag);
pr_err("\n");
}
@@ -400,7 +397,7 @@ static void print_report(struct kasan_report_info *info)
pr_err("\n");
if (addr_has_metadata(addr)) {
- print_address_description(addr, tag);
+ print_address_description(addr, tag, info);
print_memory_metadata(info->first_bad_addr);
} else {
dump_stack_lvl(KERN_ERR);
@@ -410,12 +407,20 @@ static void print_report(struct kasan_report_info *info)
static void complete_report_info(struct kasan_report_info *info)
{
void *addr = kasan_reset_tag(info->access_addr);
+ struct slab *slab;
if (info->is_free)
info->first_bad_addr = addr;
else
info->first_bad_addr = kasan_find_first_bad_addr(
info->access_addr, info->access_size);
+
+ slab = kasan_addr_to_slab(addr);
+ if (slab) {
+ info->cache = slab->slab_cache;
+ info->object = nearest_obj(info->cache, slab, addr);
+ } else
+ info->cache = info->object = NULL;
}
void kasan_report_invalid_free(void *ptr, unsigned long ip)