Skip to content

Commit ed5ec2e

Browse files
Hyesoo Yutehcaster
authored andcommitted
mm: slub: Print the broken data before restoring them
Previously, the restore occurred after printing the object in slub. After commit 47d911b ("slab: make check_object() more consistent"), the bytes are printed after the restore. This information about the bytes before the restore is highly valuable for debugging purpose. For instance, in a event of cache issue, it displays byte patterns by breaking them down into 64-bytes units. Without this information, we can only speculate on how it was broken. Hence the corrupted regions should be printed prior to the restoration process. However if an object breaks in multiple places, the same log may be output multiple times. Therefore the slub log is reported only once to prevent redundant printing, by sending a parameter indicating whether an error has occurred previously. Signed-off-by: Hyesoo Yu <[email protected]> Reviewed-by: Harry Yoo <[email protected]> Signed-off-by: Vlastimil Babka <[email protected]>
1 parent 539f552 commit ed5ec2e

File tree

1 file changed

+14
-18
lines changed

1 file changed

+14
-18
lines changed

mm/slub.c

Lines changed: 14 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1181,8 +1181,8 @@ static void restore_bytes(struct kmem_cache *s, char *message, u8 data,
11811181

11821182
static pad_check_attributes int
11831183
check_bytes_and_report(struct kmem_cache *s, struct slab *slab,
1184-
u8 *object, char *what,
1185-
u8 *start, unsigned int value, unsigned int bytes)
1184+
u8 *object, char *what, u8 *start, unsigned int value,
1185+
unsigned int bytes, bool slab_obj_print)
11861186
{
11871187
u8 *fault;
11881188
u8 *end;
@@ -1201,10 +1201,11 @@ check_bytes_and_report(struct kmem_cache *s, struct slab *slab,
12011201
if (slab_add_kunit_errors())
12021202
goto skip_bug_print;
12031203

1204-
slab_bug(s, "%s overwritten", what);
1205-
pr_err("0x%p-0x%p @offset=%tu. First byte 0x%x instead of 0x%x\n",
1206-
fault, end - 1, fault - addr,
1207-
fault[0], value);
1204+
pr_err("[%s overwritten] 0x%p-0x%p @offset=%tu. First byte 0x%x instead of 0x%x\n",
1205+
what, fault, end - 1, fault - addr, fault[0], value);
1206+
1207+
if (slab_obj_print)
1208+
object_err(s, slab, object, "Object corrupt");
12081209

12091210
skip_bug_print:
12101211
restore_bytes(s, what, value, fault, end);
@@ -1268,7 +1269,7 @@ static int check_pad_bytes(struct kmem_cache *s, struct slab *slab, u8 *p)
12681269
return 1;
12691270

12701271
return check_bytes_and_report(s, slab, p, "Object padding",
1271-
p + off, POISON_INUSE, size_from_object(s) - off);
1272+
p + off, POISON_INUSE, size_from_object(s) - off, true);
12721273
}
12731274

12741275
/* Check the pad bytes at the end of a slab page */
@@ -1318,11 +1319,11 @@ static int check_object(struct kmem_cache *s, struct slab *slab,
13181319

13191320
if (s->flags & SLAB_RED_ZONE) {
13201321
if (!check_bytes_and_report(s, slab, object, "Left Redzone",
1321-
object - s->red_left_pad, val, s->red_left_pad))
1322+
object - s->red_left_pad, val, s->red_left_pad, ret))
13221323
ret = 0;
13231324

13241325
if (!check_bytes_and_report(s, slab, object, "Right Redzone",
1325-
endobject, val, s->inuse - s->object_size))
1326+
endobject, val, s->inuse - s->object_size, ret))
13261327
ret = 0;
13271328

13281329
if (slub_debug_orig_size(s) && val == SLUB_RED_ACTIVE) {
@@ -1331,15 +1332,15 @@ static int check_object(struct kmem_cache *s, struct slab *slab,
13311332
if (s->object_size > orig_size &&
13321333
!check_bytes_and_report(s, slab, object,
13331334
"kmalloc Redzone", p + orig_size,
1334-
val, s->object_size - orig_size)) {
1335+
val, s->object_size - orig_size, ret)) {
13351336
ret = 0;
13361337
}
13371338
}
13381339
} else {
13391340
if ((s->flags & SLAB_POISON) && s->object_size < s->inuse) {
13401341
if (!check_bytes_and_report(s, slab, p, "Alignment padding",
13411342
endobject, POISON_INUSE,
1342-
s->inuse - s->object_size))
1343+
s->inuse - s->object_size, ret))
13431344
ret = 0;
13441345
}
13451346
}
@@ -1355,11 +1356,11 @@ static int check_object(struct kmem_cache *s, struct slab *slab,
13551356
if (kasan_meta_size < s->object_size - 1 &&
13561357
!check_bytes_and_report(s, slab, p, "Poison",
13571358
p + kasan_meta_size, POISON_FREE,
1358-
s->object_size - kasan_meta_size - 1))
1359+
s->object_size - kasan_meta_size - 1, ret))
13591360
ret = 0;
13601361
if (kasan_meta_size < s->object_size &&
13611362
!check_bytes_and_report(s, slab, p, "End Poison",
1362-
p + s->object_size - 1, POISON_END, 1))
1363+
p + s->object_size - 1, POISON_END, 1, ret))
13631364
ret = 0;
13641365
}
13651366
/*
@@ -1385,11 +1386,6 @@ static int check_object(struct kmem_cache *s, struct slab *slab,
13851386
ret = 0;
13861387
}
13871388

1388-
if (!ret && !slab_in_kunit_test()) {
1389-
print_trailer(s, slab, object);
1390-
add_taint(TAINT_BAD_PAGE, LOCKDEP_NOW_UNRELIABLE);
1391-
}
1392-
13931389
return ret;
13941390
}
13951391

0 commit comments

Comments
 (0)