lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Date:	Sun, 15 Jan 2012 20:58:06 +0530
From:	Rabin Vincent <rabin@....in>
To:	fengguang.wu@...el.com
Cc:	linux-kernel@...r.kernel.org
Subject: Crash in writeback:single_inode tracepoint after card removal

I'm testing SD card removal, and with tracing enabled I'm seeing a crash
in the writeback:single_inode event sometimes when a umount is done
after a card is removed with pending io.  When the problem occurs,
writeback is begin attempted with the default_backing_dev_info.  The
block bdi which was handling this device has been unregistered and it's
bdi->dev is NULL.  However it is still referenced by
inode->i_mapping->backing_dev_info, and the trace point does the
following, leading to the oops:

	TP_fast_assign(
		strncpy(__entry->name,
		dev_name(inode->i_mapping->backing_dev_info->dev),
		32);

   umount-33      0.... 10973110us : writeback_inodes_sb <-__sync_filesystem
   umount-33      0.... 10973248us : writeback_inodes_sb_nr <-__sync_filesystem
   umount-33      0.... 10973289us : bdi_queue_work <-writeback_inodes_sb_nr
   umount-33      0...1 10973336us : writeback_queue: bdi default: sb_dev 179:0 nr_pages=2153 sync_mode=0 kupdate=0 range_cyclic=0 background=0 reason=sync
 bdi-defa-14      1.... 10974021us : wb_do_writeback <-bdi_forker_thread
 bdi-defa-14      1...1 10974041us : writeback_exec: bdi default: sb_dev 179:0 nr_pages=2153 sync_mode=0 kupdate=0 range_cyclic=0 background=0 reason=sync
 bdi-defa-14      1.... 10974053us : wb_writeback <-wb_do_writeback
 bdi-defa-14      1...2 10974059us : writeback_start: bdi default: sb_dev 179:0 nr_pages=2153 sync_mode=0 kupdate=0 range_cyclic=0 background=0 reason=sync
 bdi-defa-14      1...2 10974093us : writeback_queue_io: bdi default: older=4294939114 age=0 enqueue=2 reason=sync
 bdi-defa-14      1...1 10974101us : writeback_sb_inodes <-wb_writeback
 bdi-defa-14      1...2 10974166us : writeback_single_inode <-writeback_sb_inodes

 Unable to handle kernel NULL pointer dereference at virtual address 0000002c
 pgd = c0004000
 [0000002c] *pgd=00000000
 Internal error: Oops: 17 [#1] PREEMPT SMP
 PC is at ftrace_raw_event_writeback_single_inode_template+0x60/0xe4
 LR is at ftrace_raw_event_writeback_single_inode_template+0x50/0xe4

The full trace+log is attached.  My kernel (current linus) has a delay
inserted in __mark_inode_dirty, to easily trigger the condition:

diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c
index f855916..424a655 100644
--- a/fs/fs-writeback.c
+++ b/fs/fs-writeback.c
@@ -1057,6 +1057,7 @@ static noinline void block_dump___mark_inode_dirty(struct inode *inode)
  * page->mapping->host, so the page-dirtying time is recorded in the internal
  * blockdev inode.
  */
+#include <linux/delay.h>
 void __mark_inode_dirty(struct inode *inode, int flags)
 {
 	struct super_block *sb = inode->i_sb;
@@ -1131,6 +1132,8 @@ void __mark_inode_dirty(struct inode *inode, int flags)
 					wakeup_bdi = true;
 			}
 
+			trace_printk("bdi %s\n", bdi->name);
+
 			spin_unlock(&inode->i_lock);
 			spin_lock(&bdi->wb.list_lock);
 			inode->dirtied_when = jiffies;
@@ -1139,6 +1142,14 @@ void __mark_inode_dirty(struct inode *inode, int flags)
 
 			if (wakeup_bdi)
 				bdi_wakeup_thread_delayed(bdi);
+
+			if (!strcmp(bdi->name, "block")) {
+				printk("waiting 6s, remove card\n");
+				trace_printk("waiting 6s, remove card\n");
+				msleep(6000);
+				printk("done waiting\n");
+				trace_printk("done waiting\n");
+			}
 			return;
 		}
 	}


View attachment "wblog" of type "text/plain" (38334 bytes)

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ