Skip to content

Commit ea0bb07

Browse files
Hyesoo Yuharshimogalapalli
authored andcommitted
mm: slub: call WARN() when detecting a slab corruption
[ Upstream commit 3f6f32b ] If a slab object is corrupted or an error occurs in its internal validation, continuing after restoration may cause other side effects. At this point, it is difficult to debug because the problem occurred in the past. It is useful to use WARN() to catch errors at the point of issue because WARN() could trigger panic for system debugging when panic_on_warn is enabled. WARN() is added where to detect the error on slab_err and object_err. It makes sense to only do the WARN() after printing the logs. slab_err is splited to __slab_err that calls the WARN() and it is called after printing logs. Signed-off-by: Hyesoo Yu <[email protected]> Reviewed-by: Harry Yoo <[email protected]> Signed-off-by: Vlastimil Babka <[email protected]> Stable-dep-of: b4efccec8d06 ("mm/slub: avoid accessing metadata when pointer is invalid in object_err()") Signed-off-by: Sasha Levin <[email protected]> Signed-off-by: Greg Kroah-Hartman <[email protected]> (cherry picked from commit d06b739f41dccb45c06972b4de46fc856d7411a9) Signed-off-by: Harshit Mogalapalli <[email protected]>
1 parent 17196bc commit ea0bb07

File tree

1 file changed

+29
-18
lines changed

1 file changed

+29
-18
lines changed

mm/slub.c

Lines changed: 29 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1040,7 +1040,7 @@ static void slab_bug(struct kmem_cache *s, char *fmt, ...)
10401040
vaf.fmt = fmt;
10411041
vaf.va = &args;
10421042
pr_err("=============================================================================\n");
1043-
pr_err("BUG %s (%s): %pV\n", s->name, print_tainted(), &vaf);
1043+
pr_err("BUG %s (%s): %pV\n", s ? s->name : "<unknown>", print_tainted(), &vaf);
10441044
pr_err("-----------------------------------------------------------------------------\n\n");
10451045
va_end(args);
10461046
}
@@ -1099,8 +1099,6 @@ static void print_trailer(struct kmem_cache *s, struct slab *slab, u8 *p)
10991099
/* Beginning of the filler is the free pointer */
11001100
print_section(KERN_ERR, "Padding ", p + off,
11011101
size_from_object(s) - off);
1102-
1103-
dump_stack();
11041102
}
11051103

11061104
static void object_err(struct kmem_cache *s, struct slab *slab,
@@ -1112,6 +1110,8 @@ static void object_err(struct kmem_cache *s, struct slab *slab,
11121110
slab_bug(s, "%s", reason);
11131111
print_trailer(s, slab, object);
11141112
add_taint(TAINT_BAD_PAGE, LOCKDEP_NOW_UNRELIABLE);
1113+
1114+
WARN_ON(1);
11151115
}
11161116

11171117
static bool freelist_corrupted(struct kmem_cache *s, struct slab *slab,
@@ -1128,6 +1128,17 @@ static bool freelist_corrupted(struct kmem_cache *s, struct slab *slab,
11281128
return false;
11291129
}
11301130

1131+
static void __slab_err(struct slab *slab)
1132+
{
1133+
if (slab_in_kunit_test())
1134+
return;
1135+
1136+
print_slab_info(slab);
1137+
add_taint(TAINT_BAD_PAGE, LOCKDEP_NOW_UNRELIABLE);
1138+
1139+
WARN_ON(1);
1140+
}
1141+
11311142
static __printf(3, 4) void slab_err(struct kmem_cache *s, struct slab *slab,
11321143
const char *fmt, ...)
11331144
{
@@ -1141,9 +1152,7 @@ static __printf(3, 4) void slab_err(struct kmem_cache *s, struct slab *slab,
11411152
vsnprintf(buf, sizeof(buf), fmt, args);
11421153
va_end(args);
11431154
slab_bug(s, "%s", buf);
1144-
print_slab_info(slab);
1145-
dump_stack();
1146-
add_taint(TAINT_BAD_PAGE, LOCKDEP_NOW_UNRELIABLE);
1155+
__slab_err(slab);
11471156
}
11481157

11491158
static void init_object(struct kmem_cache *s, void *object, u8 val)
@@ -1316,9 +1325,10 @@ slab_pad_check(struct kmem_cache *s, struct slab *slab)
13161325
while (end > fault && end[-1] == POISON_INUSE)
13171326
end--;
13181327

1319-
slab_err(s, slab, "Padding overwritten. 0x%p-0x%p @offset=%tu",
1320-
fault, end - 1, fault - start);
1328+
slab_bug(s, "Padding overwritten. 0x%p-0x%p @offset=%tu",
1329+
fault, end - 1, fault - start);
13211330
print_section(KERN_ERR, "Padding ", pad, remainder);
1331+
__slab_err(slab);
13221332

13231333
restore_bytes(s, "slab padding", POISON_INUSE, fault, end);
13241334
}
@@ -1634,12 +1644,12 @@ static inline int free_consistency_checks(struct kmem_cache *s,
16341644
slab_err(s, slab, "Attempt to free object(0x%p) outside of slab",
16351645
object);
16361646
} else if (!slab->slab_cache) {
1637-
pr_err("SLUB <none>: no slab for object 0x%p.\n",
1638-
object);
1639-
dump_stack();
1640-
} else
1647+
slab_err(NULL, slab, "No slab cache for object 0x%p",
1648+
object);
1649+
} else {
16411650
object_err(s, slab, object,
1642-
"page slab pointer corrupt.");
1651+
"page slab pointer corrupt.");
1652+
}
16431653
return 0;
16441654
}
16451655
return 1;
@@ -5476,14 +5486,14 @@ static int calculate_sizes(struct kmem_cache_args *args, struct kmem_cache *s)
54765486
return !!oo_objects(s->oo);
54775487
}
54785488

5479-
static void list_slab_objects(struct kmem_cache *s, struct slab *slab,
5480-
const char *text)
5489+
static void list_slab_objects(struct kmem_cache *s, struct slab *slab)
54815490
{
54825491
#ifdef CONFIG_SLUB_DEBUG
54835492
void *addr = slab_address(slab);
54845493
void *p;
54855494

5486-
slab_err(s, slab, text, s->name);
5495+
if (!slab_add_kunit_errors())
5496+
slab_bug(s, "Objects remaining on __kmem_cache_shutdown()");
54875497

54885498
spin_lock(&object_map_lock);
54895499
__fill_map(object_map, s, slab);
@@ -5498,6 +5508,8 @@ static void list_slab_objects(struct kmem_cache *s, struct slab *slab,
54985508
}
54995509
}
55005510
spin_unlock(&object_map_lock);
5511+
5512+
__slab_err(slab);
55015513
#endif
55025514
}
55035515

@@ -5518,8 +5530,7 @@ static void free_partial(struct kmem_cache *s, struct kmem_cache_node *n)
55185530
remove_partial(n, slab);
55195531
list_add(&slab->slab_list, &discard);
55205532
} else {
5521-
list_slab_objects(s, slab,
5522-
"Objects remaining in %s on __kmem_cache_shutdown()");
5533+
list_slab_objects(s, slab);
55235534
}
55245535
}
55255536
spin_unlock_irq(&n->list_lock);

0 commit comments

Comments
 (0)