[bug report] data corruption of init process
Gao Xiang
hsiangkao at linux.alibaba.com
Tue Jan 21 14:27:21 AEDT 2025
On 2025/1/21 01:36, Stefan Kerkmann wrote:
> Hi Gao,
>
> I have enabled KASAN and applied your requested changes, but nothing suspicious happened.
Sigh...
>
>> - Could we get the exact file offset of `init` which init process is
>> crashed? It will help us to chase down the the primary scene.
>
> I'll try to track that down. If you have any hints how to-do that let me know :-).
Many thanks for the test...
I just hacked some code but un-tested as below:
diff --git a/kernel/exit.c b/kernel/exit.c
index 1dcddfe537ee..868fea16732f 100644
--- a/kernel/exit.c
+++ b/kernel/exit.c
@@ -873,6 +873,8 @@ static void synchronize_group_exit(struct task_struct *tsk, long code)
spin_unlock_irq(&sighand->siglock);
}
+extern struct inode *erofs_iget(struct super_block *sb, u64 nid);
+
void __noreturn do_exit(long code)
{
struct task_struct *tsk = current;
@@ -903,9 +905,59 @@ void __noreturn do_exit(long code)
* If the last thread of global init has exited, panic
* immediately to get a useable coredump.
*/
- if (unlikely(is_global_init(tsk)))
+ if (unlikely(is_global_init(tsk))) {
+ struct path path;
+ struct inode *inode;
+
+ get_fs_pwd(tsk->fs, &path);
+
+ inode = d_inode(path.dentry);
+ if (inode && inode->i_sb->s_magic == EROFS_SUPER_MAGIC_V1) {
+ struct inode *inode;
+ int i = 0;
+
+ inode = erofs_iget(inode->i_sb, 190291);
+ if (IS_ERR(inode))
+ goto skip;
+
+ for (i = 0; i < 30; ++i) {
+ struct page *page = find_get_page(inode->i_mapping, i);
+ void *data;
+
+ if (!page)
+ continue;
+ data = kmap_local_page(page);
+
+ hash = fnv_32_buf(data, PAGE_SIZE, FNV1_32_INIT);
+ pr_err("%px i_ino %lu, index %lu dst %px (%x) err %d",
+ page, page->mapping->host->i_ino, i, ptr, hash);
+ kunmap_local(data);
+ }
+ iput(inode);
+
+ inode = erofs_iget(inode->i_sb, 868416);
+ if (IS_ERR(inode))
+ goto skip;
+
+ for (i = 0; i < 19; ++i) {
+ struct page *page = find_get_page(inode->i_mapping, i);
+ void *data;
+
+ if (!page)
+ continue;
+ data = kmap_local_page(page);
+ hash = fnv_32_buf(data, PAGE_SIZE, FNV1_32_INIT);
+ pr_err("%px i_ino %lu, index %lu dst %px (%x) err %d",
+ page, page->mapping->host->i_ino, i, ptr, hash);
+ kunmap_local(data);
+ }
+ iput(inode);
+ }
+skip:
panic("Attempted to kill init! exitcode=0x%08x\n",
tsk->signal->group_exit_code ?: (int)code);
+ }
+
#ifdef CONFIG_POSIX_TIMERS
hrtimer_cancel(&tsk->signal->real_timer);
You could follow the idea to dump the page cache data when init
is killed, I wonder the output...
Thanks,
Gao Xiang
More information about the Linux-erofs
mailing list