[PATCH] debugobjects: turn off debug_objects_enabled from debug_objects_oom()

From: Tetsuo Handa
Date: Mon May 29 2023 - 10:40:23 EST


syzbot is reporting false positive ODEBUG message immediately after
ODEBUG was disabled due to OOM.

[ 1062.309646][T22911] ODEBUG: Out of memory. ODEBUG disabled
[ 1062.886755][ T5171] ------------[ cut here ]------------
[ 1062.892770][ T5171] ODEBUG: assert_init not available (active state 0) object: ffffc900056afb20 object type: timer_list hint: process_timeout+0x0/0x40

This race happened because debug_objects_oom() emitted OOM message but did
not turn off debug_objects_enabled, and debug_print_object() did not check
debug_objects_enabled when calling WARN().

CPU 0 [ T5171] CPU 1 [T22911]
-------------- --------------
debug_object_assert_init() {
if (!debug_objects_enabled)
return;
db = get_bucket((unsigned long) addr); // Finds a bucket, but...
debug_objects_oom() {
pr_warn("Out of memory. ODEBUG disabled\n");
// all buckets get emptied here, and...
hlist_move_list(&db->list, &freelist);
}
lookup_object_or_alloc(addr, db, descr, false, true) {
lookup_object(addr, b) {
return NULL; // this bucket is already empty.
}
if (!descr->is_static_object || !descr->is_static_object(addr))
return ERR_PTR(-ENOENT);
}
if (!obj) { // obj == ERR_PTR(-ENOENT) because non-static object.
debug_objects_oom();
return;
}
debug_print_object(&o, "assert_init") {
// False positive due to not checking debug_objects_enabled.
WARN(1, KERN_ERR "ODEBUG: %s %s (active state %u) "
"object: %p object type: %s hint: %pS\n", ...);
}
}

Reported-by: syzbot <syzbot+7937ba6a50bdd00fffdf@xxxxxxxxxxxxxxxxxxxxxxxxx>
Closes: https://syzkaller.appspot.com/bug?extid=7937ba6a50bdd00fffdf
Signed-off-by: Tetsuo Handa <penguin-kernel@xxxxxxxxxxxxxxxxxxx>
---
lib/debugobjects.c | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/lib/debugobjects.c b/lib/debugobjects.c
index 984985c39c9b..63974e9edac5 100644
--- a/lib/debugobjects.c
+++ b/lib/debugobjects.c
@@ -466,6 +466,7 @@ static void debug_objects_oom(void)
unsigned long flags;
int i;

+ debug_objects_enabled = 0;
pr_warn("Out of memory. ODEBUG disabled\n");

for (i = 0; i < ODEBUG_HASH_SIZE; i++, db++) {
@@ -502,10 +503,10 @@ static void debug_print_object(struct debug_obj *obj, char *msg)
void *hint = descr->debug_hint ?
descr->debug_hint(obj->object) : NULL;
limit++;
- WARN(1, KERN_ERR "ODEBUG: %s %s (active state %u) "
- "object: %p object type: %s hint: %pS\n",
- msg, obj_states[obj->state], obj->astate,
- obj->object, descr->name, hint);
+ WARN(debug_objects_enabled, KERN_ERR
+ "ODEBUG: %s %s (active state %u) object: %p object type: %s hint: %pS\n",
+ msg, obj_states[obj->state], obj->astate,
+ obj->object, descr->name, hint);
}
debug_objects_warnings++;
}
--
2.18.4