Skip to content

Commit 17196bc

Browse files
Hyesoo Yuharshimogalapalli
authored andcommitted
mm: slub: Print the broken data before restoring them
[ Upstream commit ed5ec2e ] 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]> 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 20a54a8db4dd85a30e2005081ab386f0c4cb3d3d) Signed-off-by: Harshit Mogalapalli <[email protected]>
1 parent e7faf56 commit 17196bc

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
@@ -1195,8 +1195,8 @@ static void restore_bytes(struct kmem_cache *s, char *message, u8 data,
11951195

11961196
static pad_check_attributes int
11971197
check_bytes_and_report(struct kmem_cache *s, struct slab *slab,
1198-
u8 *object, char *what,
1199-
u8 *start, unsigned int value, unsigned int bytes)
1198+
u8 *object, char *what, u8 *start, unsigned int value,
1199+
unsigned int bytes, bool slab_obj_print)
12001200
{
12011201
u8 *fault;
12021202
u8 *end;
@@ -1215,10 +1215,11 @@ check_bytes_and_report(struct kmem_cache *s, struct slab *slab,
12151215
if (slab_add_kunit_errors())
12161216
goto skip_bug_print;
12171217

1218-
slab_bug(s, "%s overwritten", what);
1219-
pr_err("0x%p-0x%p @offset=%tu. First byte 0x%x instead of 0x%x\n",
1220-
fault, end - 1, fault - addr,
1221-
fault[0], value);
1218+
pr_err("[%s overwritten] 0x%p-0x%p @offset=%tu. First byte 0x%x instead of 0x%x\n",
1219+
what, fault, end - 1, fault - addr, fault[0], value);
1220+
1221+
if (slab_obj_print)
1222+
object_err(s, slab, object, "Object corrupt");
12221223

12231224
skip_bug_print:
12241225
restore_bytes(s, what, value, fault, end);
@@ -1282,7 +1283,7 @@ static int check_pad_bytes(struct kmem_cache *s, struct slab *slab, u8 *p)
12821283
return 1;
12831284

12841285
return check_bytes_and_report(s, slab, p, "Object padding",
1285-
p + off, POISON_INUSE, size_from_object(s) - off);
1286+
p + off, POISON_INUSE, size_from_object(s) - off, true);
12861287
}
12871288

12881289
/* Check the pad bytes at the end of a slab page */
@@ -1332,11 +1333,11 @@ static int check_object(struct kmem_cache *s, struct slab *slab,
13321333

13331334
if (s->flags & SLAB_RED_ZONE) {
13341335
if (!check_bytes_and_report(s, slab, object, "Left Redzone",
1335-
object - s->red_left_pad, val, s->red_left_pad))
1336+
object - s->red_left_pad, val, s->red_left_pad, ret))
13361337
ret = 0;
13371338

13381339
if (!check_bytes_and_report(s, slab, object, "Right Redzone",
1339-
endobject, val, s->inuse - s->object_size))
1340+
endobject, val, s->inuse - s->object_size, ret))
13401341
ret = 0;
13411342

13421343
if (slub_debug_orig_size(s) && val == SLUB_RED_ACTIVE) {
@@ -1345,15 +1346,15 @@ static int check_object(struct kmem_cache *s, struct slab *slab,
13451346
if (s->object_size > orig_size &&
13461347
!check_bytes_and_report(s, slab, object,
13471348
"kmalloc Redzone", p + orig_size,
1348-
val, s->object_size - orig_size)) {
1349+
val, s->object_size - orig_size, ret)) {
13491350
ret = 0;
13501351
}
13511352
}
13521353
} else {
13531354
if ((s->flags & SLAB_POISON) && s->object_size < s->inuse) {
13541355
if (!check_bytes_and_report(s, slab, p, "Alignment padding",
13551356
endobject, POISON_INUSE,
1356-
s->inuse - s->object_size))
1357+
s->inuse - s->object_size, ret))
13571358
ret = 0;
13581359
}
13591360
}
@@ -1369,11 +1370,11 @@ static int check_object(struct kmem_cache *s, struct slab *slab,
13691370
if (kasan_meta_size < s->object_size - 1 &&
13701371
!check_bytes_and_report(s, slab, p, "Poison",
13711372
p + kasan_meta_size, POISON_FREE,
1372-
s->object_size - kasan_meta_size - 1))
1373+
s->object_size - kasan_meta_size - 1, ret))
13731374
ret = 0;
13741375
if (kasan_meta_size < s->object_size &&
13751376
!check_bytes_and_report(s, slab, p, "End Poison",
1376-
p + s->object_size - 1, POISON_END, 1))
1377+
p + s->object_size - 1, POISON_END, 1, ret))
13771378
ret = 0;
13781379
}
13791380
/*
@@ -1399,11 +1400,6 @@ static int check_object(struct kmem_cache *s, struct slab *slab,
13991400
ret = 0;
14001401
}
14011402

1402-
if (!ret && !slab_in_kunit_test()) {
1403-
print_trailer(s, slab, object);
1404-
add_taint(TAINT_BAD_PAGE, LOCKDEP_NOW_UNRELIABLE);
1405-
}
1406-
14071403
return ret;
14081404
}
14091405

0 commit comments

Comments
 (0)