Check list_head->next/prev for NULL in __list_del_entry_valid
Subsystems (3)
Steve, all,
I am trying to track down a NULL deref that happens during cifs_reconnect(). I don't have the root cause yet but I can mitigate the issue slightly by adding NULL checks in the list_debug code and avoid the bug I am chasing from causing a NULL deref to to just become a harmless run-time check.
This is not a fix for the underlying bug, I have yet for find it, but it will avoif the debugging code from making things worse by causing a crash.
During cifs_reconnect() we are calling
list_del_init(&mid_entry->qhead);
at this point entry->prev->next is equal to entry and all is good, but entry->next is NULL which causes the crash in list_debug.c:__list_del_entry_valid() :
CHECK_DATA_CORRUPTION(next->prev != entry,
Since __list_del_entry_valid() is used to check that the pointers are all valid, I think is is acceptable to also add NULL checks here as NULL is a common value for invalid pointers.
A message that is not in the archive (sent off-list or not yet received): 20180110000349.14963-1-lsahlber-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org
PATCH 1/1 list_debug: check prev/next for NULL when checking list_head for validity
--- lib/list_debug.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-)
lib/list_debug.c +7 -1
@@ -42,7 +42,13 @@ bool __list_del_entry_valid(struct list_head *entry) prev = entry->prev; next = entry->next; -if (CHECK_DATA_CORRUPTION (next ==LIST_POISON1 , +if (CHECK_DATA_CORRUPTION (next ==NULL , +"list_del corruption, %p->next is NULL (%p)\n" , + entry,LIST_POISON1 ) || +CHECK_DATA_CORRUPTION (prev ==NULL , +"list_del corruption, %p->prev is NULL (%p)\n" , + entry,LIST_POISON2 ) || +CHECK_DATA_CORRUPTION (next ==LIST_POISON1 ,"list_del corruption, %p->next is LIST_POISON1 (%p)\n" , entry,LIST_POISON1 ) || CHECK_DATA_CORRUPTION(prev == LIST_POISON2,
Signature · 1 line
2.13.3