* [PATCH] writeback: expired dirty inodes can lead to a NULL dereference kernel panic issue in 'move_expired_inodes' function
@ 2022-04-08 7:18 Paran Lee
2022-04-08 9:25 ` Colin King (gmail)
2022-04-08 11:25 ` Greg KH
0 siblings, 2 replies; 5+ messages in thread
From: Paran Lee @ 2022-04-08 7:18 UTC (permalink / raw)
To: colin.i.king; +Cc: stable, Austin Kim
writeback: expired dirty inodes can lead to a NULL dereference kernel panic issue in 'move_expired_inodes' function
Hello, Colin Ian King.
I am Paran Lee.
While tracing the null dereference kernel panic issue during the stress-ng(stress-ng-proc) test,
I found the inode code block that could cause a null dereference kernel panic.
If this issue is confirmed as a bug that may have occurred in the past, wouldn't it be added to the link below?
@ Bugs found with stress-ng
- https://github.com/ColinIanKing/stress-ng#bugs-found-with-stress-ng
* kernel log
[21881.096120] ICMPv6: process `stress-ng-procf' is using deprecated sysctl (syscall) net.ipv6.neigh.default.base_reachable_time - use net.ipv6.neigh.default.base_reachable_time_ms instead
[22009.051158] BUG: unable to handle kernel NULL pointer dereference at 0000000000000008
[22009.051167] IP: move_expired_inodes+0x59/0x1a0
[22009.051168] PGD 0 P4D 0
[22009.051170] Oops: 0002 [#1] SMP NOPTI
...
[22009.051221] RIP: 0010:move_expired_inodes+0x59/0x1a0
...
[22009.051257] Call Trace:
[22009.051260] queue_io+0x66/0x110
[22009.051262] wb_writeback+0x253/0x300
[22009.051264] wb_workfn+0xc0/0x400
[22009.051265] ? wb_workfn+0xc0/0x400
[22009.051268] ? __switch_to_asm+0x35/0x70
[22009.051272] process_one_work+0x1de/0x420
[22009.051274] worker_thread+0x32/0x410
[22009.051276] kthread+0x121/0x140
[22009.051277] ? process_one_work+0x420/0x420
[22009.051279] ? kthread_create_worker_on_cpu+0x70/0x70
[22009.051280] ret_from_fork+0x1f/0x40
[22009.051282] Code: 04 25 28 00 00 00 48 89 45 d0 31 c0 4c 89 75 c8 c7 45 b0 00 00 00 00 c7 45 b4 00 00 00 00 eb 76 48 8b 3b 48 8b 43 08 83 45 b0 01 <48> 89 47 08 48 89 38 48 8b 45 c0 48 89 58 08 48 89 03 48 8d 43
[22009.051293] RIP: move_expired_inodes+0x59/0x1a0 RSP: ffffa2f68413bcb0
* trace log on crash utility
KERNEL: vmlinux-4.15.0-166-generic
DUMPFILE: 202204072123-wb_inode-delaying_queue-list-null-check/dump.202204072123 [PARTIAL DUMP]
CPUS: 4
DATE: Fri Apr 8 06:23:30 2022
UPTIME: 01:35:27
LOAD AVERAGE: 8.30, 8.37, 9.17
TASKS: 668
NODENAME: ubuntu1804
RELEASE: 4.15.0-166-generic
VERSION: #174-Ubuntu SMP Wed Dec 8 19:07:44 UTC 2021
MACHINE: x86_64 (2394 Mhz)
MEMORY: 16 GB
PANIC: "BUG: unable to handle kernel NULL pointer dereference at 0000000000000008"
PID: 22864
COMMAND: "kworker/u8:0"
TASK: ffff91490b55d880 [THREAD_INFO: ffff91490b55d880]
CPU: 0
STATE: TASK_RUNNING (PANIC)
crash> bt
...
#9 [ffffa2f68413bc00] page_fault at ffffffffae401615
[exception RIP: move_expired_inodes+89]
RIP: ffffffffadcb11f9 RSP: ffffa2f68413bcb0 RFLAGS: 00010202
RAX: 0000000000000000 RBX: ffff9148083af9b8 RCX: ffff91496659a090
RDX: 000000010052d046 RSI: ffff91496659a080 RDI: 0000000000000000
RBP: ffffa2f68413bd08 R8: ffff91496676727f R9: ffff914951111f76
R10: ffffa2f68413bdf8 R11: 0000000000000334 R12: 0000000000000000
R13: ffff91496659a070 R14: ffffa2f68413bcc8 R15: ffff91496659a080
ORIG_RAX: ffffffffffffffff CS: 0010 SS: 0018
#10 [ffffa2f68413bd10] queue_io at ffffffffadcb32d6
#11 [ffffa2f68413bd48] wb_writeback at ffffffffadcb77a3
#12 [ffffa2f68413bde8] wb_workfn at ffffffffadcb7eb0
#13 [ffffa2f68413be80] process_one_work at ffffffffadaaa68e
#14 [ffffa2f68413bec8] worker_thread at ffffffffadaaa902
#15 [ffffa2f68413bf08] kthread at ffffffffadab1361
#16 [ffffa2f68413bf50] ret_from_fork at ffffffffae4001ef
crash> dis ffffffffadcb32c6 20
...
0xffffffffadcb32c6 <queue_io+86>: jg 0xffffffffadcb32e0 <queue_io+112>
0xffffffffadcb32c8 <queue_io+88>: mov %rsi,%r14
0xffffffffadcb32cb <queue_io+91>: mov %r12,%rsi
0xffffffffadcb32ce <queue_io+94>: mov %rdx,%r13
0xffffffffadcb32d1 <queue_io+97>: callq 0xffffffffadcb11a0 <move_expired_inodes>
crash> dis 0xffffffffadcb11a0
0xffffffffadcb11a0 <move_expired_inodes>: nopl 0x0(%rax,%rax,1) [FTRACE NOP]
...
0xffffffffadcb11ec <move_expired_inodes+76>: jmp 0xffffffffadcb1264 <move_expired_inodes+196>
0xffffffffadcb11ee <move_expired_inodes+78>: mov (%rbx),%rdi
0xffffffffadcb11f1 <move_expired_inodes+81>: mov 0x8(%rbx),%rax
0xffffffffadcb11f5 <move_expired_inodes+85>: addl $0x1,-0x50(%rbp)
0xffffffffadcb11f9 <move_expired_inodes+89>: mov %rax,0x8(%rdi) <<<<<< Don't you think this is the NULL dereference RIP point of it?
0xffffffffadcb11fd <move_expired_inodes+93>: mov %rdi,(%rax)
...
0xffffffffadcb121e <move_expired_inodes+126>: callq 0xffffffffae3cd460 <_raw_spin_lock>
Have a good day.
Paran Lee.
Signed-off-by: Paran Lee <p4ranlee@gmail.com>
---
fs/fs-writeback.c | 11 +++++++++--
1 file changed, 9 insertions(+), 2 deletions(-)
diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c
index 591fe9cf1659..23a7a567e443 100644
--- a/fs/fs-writeback.c
+++ b/fs/fs-writeback.c
@@ -1357,12 +1357,14 @@ static int move_expired_inodes(struct list_head *delaying_queue,
LIST_HEAD(tmp);
struct list_head *pos, *node;
struct super_block *sb = NULL;
- struct inode *inode;
+ struct inode *inode = NULL;
int do_sb_sort = 0;
int moved = 0;
while (!list_empty(delaying_queue)) {
inode = wb_inode(delaying_queue->prev);
+ if(!inode)
+ continue;
if (inode_dirtied_after(inode, dirtied_before))
break;
list_move(&inode->i_io_list, &tmp);
@@ -1385,7 +1387,12 @@ static int move_expired_inodes(struct list_head *delaying_queue,
/* Move inodes from one superblock together */
while (!list_empty(&tmp)) {
- sb = wb_inode(tmp.prev)->i_sb;
+ inode = wb_inode(tmp.prev);
+ if(!inode)
+ continue;
+ sb = inode->i_sb;
+ if(!sb)
+ continue;
list_for_each_prev_safe(pos, node, &tmp) {
inode = wb_inode(pos);
if (inode->i_sb == sb)
--
2.25.1
^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [PATCH] writeback: expired dirty inodes can lead to a NULL dereference kernel panic issue in 'move_expired_inodes' function
2022-04-08 7:18 [PATCH] writeback: expired dirty inodes can lead to a NULL dereference kernel panic issue in 'move_expired_inodes' function Paran Lee
@ 2022-04-08 9:25 ` Colin King (gmail)
2022-04-08 11:25 ` Greg KH
1 sibling, 0 replies; 5+ messages in thread
From: Colin King (gmail) @ 2022-04-08 9:25 UTC (permalink / raw)
To: Paran Lee; +Cc: stable, Austin Kim
Hi Paran Lee,
On 08/04/2022 08:18, Paran Lee wrote:
> writeback: expired dirty inodes can lead to a NULL dereference kernel panic issue in 'move_expired_inodes' function
>
> Hello, Colin Ian King.
>
> I am Paran Lee.
>
> While tracing the null dereference kernel panic issue during the stress-ng(stress-ng-proc) test,
> I found the inode code block that could cause a null dereference kernel panic.
>
> If this issue is confirmed as a bug that may have occurred in the past, wouldn't it be added to the link below?
The list is not necessarily a definitive list, I may accidentally miss
items off it and/or if I'm not directly informed of issues found by the
stress-ng tool.
Colin
>
> @ Bugs found with stress-ng
> - https://github.com/ColinIanKing/stress-ng#bugs-found-with-stress-ng
>
> * kernel log
>
> [21881.096120] ICMPv6: process `stress-ng-procf' is using deprecated sysctl (syscall) net.ipv6.neigh.default.base_reachable_time - use net.ipv6.neigh.default.base_reachable_time_ms instead
> [22009.051158] BUG: unable to handle kernel NULL pointer dereference at 0000000000000008
> [22009.051167] IP: move_expired_inodes+0x59/0x1a0
> [22009.051168] PGD 0 P4D 0
> [22009.051170] Oops: 0002 [#1] SMP NOPTI
> ...
> [22009.051221] RIP: 0010:move_expired_inodes+0x59/0x1a0
> ...
> [22009.051257] Call Trace:
> [22009.051260] queue_io+0x66/0x110
> [22009.051262] wb_writeback+0x253/0x300
> [22009.051264] wb_workfn+0xc0/0x400
> [22009.051265] ? wb_workfn+0xc0/0x400
> [22009.051268] ? __switch_to_asm+0x35/0x70
> [22009.051272] process_one_work+0x1de/0x420
> [22009.051274] worker_thread+0x32/0x410
> [22009.051276] kthread+0x121/0x140
> [22009.051277] ? process_one_work+0x420/0x420
> [22009.051279] ? kthread_create_worker_on_cpu+0x70/0x70
> [22009.051280] ret_from_fork+0x1f/0x40
> [22009.051282] Code: 04 25 28 00 00 00 48 89 45 d0 31 c0 4c 89 75 c8 c7 45 b0 00 00 00 00 c7 45 b4 00 00 00 00 eb 76 48 8b 3b 48 8b 43 08 83 45 b0 01 <48> 89 47 08 48 89 38 48 8b 45 c0 48 89 58 08 48 89 03 48 8d 43
> [22009.051293] RIP: move_expired_inodes+0x59/0x1a0 RSP: ffffa2f68413bcb0
>
> * trace log on crash utility
>
> KERNEL: vmlinux-4.15.0-166-generic
> DUMPFILE: 202204072123-wb_inode-delaying_queue-list-null-check/dump.202204072123 [PARTIAL DUMP]
> CPUS: 4
> DATE: Fri Apr 8 06:23:30 2022
> UPTIME: 01:35:27
> LOAD AVERAGE: 8.30, 8.37, 9.17
> TASKS: 668
> NODENAME: ubuntu1804
> RELEASE: 4.15.0-166-generic
> VERSION: #174-Ubuntu SMP Wed Dec 8 19:07:44 UTC 2021
> MACHINE: x86_64 (2394 Mhz)
> MEMORY: 16 GB
> PANIC: "BUG: unable to handle kernel NULL pointer dereference at 0000000000000008"
> PID: 22864
> COMMAND: "kworker/u8:0"
> TASK: ffff91490b55d880 [THREAD_INFO: ffff91490b55d880]
> CPU: 0
> STATE: TASK_RUNNING (PANIC)
>
> crash> bt
> ...
> #9 [ffffa2f68413bc00] page_fault at ffffffffae401615
> [exception RIP: move_expired_inodes+89]
> RIP: ffffffffadcb11f9 RSP: ffffa2f68413bcb0 RFLAGS: 00010202
> RAX: 0000000000000000 RBX: ffff9148083af9b8 RCX: ffff91496659a090
> RDX: 000000010052d046 RSI: ffff91496659a080 RDI: 0000000000000000
> RBP: ffffa2f68413bd08 R8: ffff91496676727f R9: ffff914951111f76
> R10: ffffa2f68413bdf8 R11: 0000000000000334 R12: 0000000000000000
> R13: ffff91496659a070 R14: ffffa2f68413bcc8 R15: ffff91496659a080
> ORIG_RAX: ffffffffffffffff CS: 0010 SS: 0018
> #10 [ffffa2f68413bd10] queue_io at ffffffffadcb32d6
> #11 [ffffa2f68413bd48] wb_writeback at ffffffffadcb77a3
> #12 [ffffa2f68413bde8] wb_workfn at ffffffffadcb7eb0
> #13 [ffffa2f68413be80] process_one_work at ffffffffadaaa68e
> #14 [ffffa2f68413bec8] worker_thread at ffffffffadaaa902
> #15 [ffffa2f68413bf08] kthread at ffffffffadab1361
> #16 [ffffa2f68413bf50] ret_from_fork at ffffffffae4001ef
>
> crash> dis ffffffffadcb32c6 20
> ...
> 0xffffffffadcb32c6 <queue_io+86>: jg 0xffffffffadcb32e0 <queue_io+112>
> 0xffffffffadcb32c8 <queue_io+88>: mov %rsi,%r14
> 0xffffffffadcb32cb <queue_io+91>: mov %r12,%rsi
> 0xffffffffadcb32ce <queue_io+94>: mov %rdx,%r13
> 0xffffffffadcb32d1 <queue_io+97>: callq 0xffffffffadcb11a0 <move_expired_inodes>
>
> crash> dis 0xffffffffadcb11a0
> 0xffffffffadcb11a0 <move_expired_inodes>: nopl 0x0(%rax,%rax,1) [FTRACE NOP]
> ...
> 0xffffffffadcb11ec <move_expired_inodes+76>: jmp 0xffffffffadcb1264 <move_expired_inodes+196>
> 0xffffffffadcb11ee <move_expired_inodes+78>: mov (%rbx),%rdi
> 0xffffffffadcb11f1 <move_expired_inodes+81>: mov 0x8(%rbx),%rax
> 0xffffffffadcb11f5 <move_expired_inodes+85>: addl $0x1,-0x50(%rbp)
> 0xffffffffadcb11f9 <move_expired_inodes+89>: mov %rax,0x8(%rdi) <<<<<< Don't you think this is the NULL dereference RIP point of it?
> 0xffffffffadcb11fd <move_expired_inodes+93>: mov %rdi,(%rax)
> ...
> 0xffffffffadcb121e <move_expired_inodes+126>: callq 0xffffffffae3cd460 <_raw_spin_lock>
>
> Have a good day.
> Paran Lee.
>
> Signed-off-by: Paran Lee <p4ranlee@gmail.com>
> ---
> fs/fs-writeback.c | 11 +++++++++--
> 1 file changed, 9 insertions(+), 2 deletions(-)
>
> diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c
> index 591fe9cf1659..23a7a567e443 100644
> --- a/fs/fs-writeback.c
> +++ b/fs/fs-writeback.c
> @@ -1357,12 +1357,14 @@ static int move_expired_inodes(struct list_head *delaying_queue,
> LIST_HEAD(tmp);
> struct list_head *pos, *node;
> struct super_block *sb = NULL;
> - struct inode *inode;
> + struct inode *inode = NULL;
> int do_sb_sort = 0;
> int moved = 0;
>
> while (!list_empty(delaying_queue)) {
> inode = wb_inode(delaying_queue->prev);
> + if(!inode)
> + continue;
> if (inode_dirtied_after(inode, dirtied_before))
> break;
> list_move(&inode->i_io_list, &tmp);
> @@ -1385,7 +1387,12 @@ static int move_expired_inodes(struct list_head *delaying_queue,
>
> /* Move inodes from one superblock together */
> while (!list_empty(&tmp)) {
> - sb = wb_inode(tmp.prev)->i_sb;
> + inode = wb_inode(tmp.prev);
> + if(!inode)
> + continue;
> + sb = inode->i_sb;
> + if(!sb)
> + continue;
> list_for_each_prev_safe(pos, node, &tmp) {
> inode = wb_inode(pos);
> if (inode->i_sb == sb)
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] writeback: expired dirty inodes can lead to a NULL dereference kernel panic issue in 'move_expired_inodes' function
2022-04-08 7:18 [PATCH] writeback: expired dirty inodes can lead to a NULL dereference kernel panic issue in 'move_expired_inodes' function Paran Lee
2022-04-08 9:25 ` Colin King (gmail)
@ 2022-04-08 11:25 ` Greg KH
1 sibling, 0 replies; 5+ messages in thread
From: Greg KH @ 2022-04-08 11:25 UTC (permalink / raw)
To: Paran Lee; +Cc: colin.i.king, stable, Austin Kim
On Fri, Apr 08, 2022 at 04:18:33PM +0900, Paran Lee wrote:
> writeback: expired dirty inodes can lead to a NULL dereference kernel panic issue in 'move_expired_inodes' function
>
> Hello, Colin Ian King.
>
> I am Paran Lee.
>
> While tracing the null dereference kernel panic issue during the stress-ng(stress-ng-proc) test,
> I found the inode code block that could cause a null dereference kernel panic.
>
> If this issue is confirmed as a bug that may have occurred in the past, wouldn't it be added to the link below?
>
> @ Bugs found with stress-ng
> - https://github.com/ColinIanKing/stress-ng#bugs-found-with-stress-ng
>
> * kernel log
>
> [21881.096120] ICMPv6: process `stress-ng-procf' is using deprecated sysctl (syscall) net.ipv6.neigh.default.base_reachable_time - use net.ipv6.neigh.default.base_reachable_time_ms instead
> [22009.051158] BUG: unable to handle kernel NULL pointer dereference at 0000000000000008
> [22009.051167] IP: move_expired_inodes+0x59/0x1a0
> [22009.051168] PGD 0 P4D 0
> [22009.051170] Oops: 0002 [#1] SMP NOPTI
> ...
> [22009.051221] RIP: 0010:move_expired_inodes+0x59/0x1a0
> ...
> [22009.051257] Call Trace:
> [22009.051260] queue_io+0x66/0x110
> [22009.051262] wb_writeback+0x253/0x300
> [22009.051264] wb_workfn+0xc0/0x400
> [22009.051265] ? wb_workfn+0xc0/0x400
> [22009.051268] ? __switch_to_asm+0x35/0x70
> [22009.051272] process_one_work+0x1de/0x420
> [22009.051274] worker_thread+0x32/0x410
> [22009.051276] kthread+0x121/0x140
> [22009.051277] ? process_one_work+0x420/0x420
> [22009.051279] ? kthread_create_worker_on_cpu+0x70/0x70
> [22009.051280] ret_from_fork+0x1f/0x40
> [22009.051282] Code: 04 25 28 00 00 00 48 89 45 d0 31 c0 4c 89 75 c8 c7 45 b0 00 00 00 00 c7 45 b4 00 00 00 00 eb 76 48 8b 3b 48 8b 43 08 83 45 b0 01 <48> 89 47 08 48 89 38 48 8b 45 c0 48 89 58 08 48 89 03 48 8d 43
> [22009.051293] RIP: move_expired_inodes+0x59/0x1a0 RSP: ffffa2f68413bcb0
>
> * trace log on crash utility
>
> KERNEL: vmlinux-4.15.0-166-generic
> DUMPFILE: 202204072123-wb_inode-delaying_queue-list-null-check/dump.202204072123 [PARTIAL DUMP]
> CPUS: 4
> DATE: Fri Apr 8 06:23:30 2022
> UPTIME: 01:35:27
> LOAD AVERAGE: 8.30, 8.37, 9.17
> TASKS: 668
> NODENAME: ubuntu1804
> RELEASE: 4.15.0-166-generic
> VERSION: #174-Ubuntu SMP Wed Dec 8 19:07:44 UTC 2021
> MACHINE: x86_64 (2394 Mhz)
> MEMORY: 16 GB
> PANIC: "BUG: unable to handle kernel NULL pointer dereference at 0000000000000008"
> PID: 22864
> COMMAND: "kworker/u8:0"
> TASK: ffff91490b55d880 [THREAD_INFO: ffff91490b55d880]
> CPU: 0
> STATE: TASK_RUNNING (PANIC)
>
> crash> bt
> ...
> #9 [ffffa2f68413bc00] page_fault at ffffffffae401615
> [exception RIP: move_expired_inodes+89]
> RIP: ffffffffadcb11f9 RSP: ffffa2f68413bcb0 RFLAGS: 00010202
> RAX: 0000000000000000 RBX: ffff9148083af9b8 RCX: ffff91496659a090
> RDX: 000000010052d046 RSI: ffff91496659a080 RDI: 0000000000000000
> RBP: ffffa2f68413bd08 R8: ffff91496676727f R9: ffff914951111f76
> R10: ffffa2f68413bdf8 R11: 0000000000000334 R12: 0000000000000000
> R13: ffff91496659a070 R14: ffffa2f68413bcc8 R15: ffff91496659a080
> ORIG_RAX: ffffffffffffffff CS: 0010 SS: 0018
> #10 [ffffa2f68413bd10] queue_io at ffffffffadcb32d6
> #11 [ffffa2f68413bd48] wb_writeback at ffffffffadcb77a3
> #12 [ffffa2f68413bde8] wb_workfn at ffffffffadcb7eb0
> #13 [ffffa2f68413be80] process_one_work at ffffffffadaaa68e
> #14 [ffffa2f68413bec8] worker_thread at ffffffffadaaa902
> #15 [ffffa2f68413bf08] kthread at ffffffffadab1361
> #16 [ffffa2f68413bf50] ret_from_fork at ffffffffae4001ef
>
> crash> dis ffffffffadcb32c6 20
> ...
> 0xffffffffadcb32c6 <queue_io+86>: jg 0xffffffffadcb32e0 <queue_io+112>
> 0xffffffffadcb32c8 <queue_io+88>: mov %rsi,%r14
> 0xffffffffadcb32cb <queue_io+91>: mov %r12,%rsi
> 0xffffffffadcb32ce <queue_io+94>: mov %rdx,%r13
> 0xffffffffadcb32d1 <queue_io+97>: callq 0xffffffffadcb11a0 <move_expired_inodes>
>
> crash> dis 0xffffffffadcb11a0
> 0xffffffffadcb11a0 <move_expired_inodes>: nopl 0x0(%rax,%rax,1) [FTRACE NOP]
> ...
> 0xffffffffadcb11ec <move_expired_inodes+76>: jmp 0xffffffffadcb1264 <move_expired_inodes+196>
> 0xffffffffadcb11ee <move_expired_inodes+78>: mov (%rbx),%rdi
> 0xffffffffadcb11f1 <move_expired_inodes+81>: mov 0x8(%rbx),%rax
> 0xffffffffadcb11f5 <move_expired_inodes+85>: addl $0x1,-0x50(%rbp)
> 0xffffffffadcb11f9 <move_expired_inodes+89>: mov %rax,0x8(%rdi) <<<<<< Don't you think this is the NULL dereference RIP point of it?
> 0xffffffffadcb11fd <move_expired_inodes+93>: mov %rdi,(%rax)
> ...
> 0xffffffffadcb121e <move_expired_inodes+126>: callq 0xffffffffae3cd460 <_raw_spin_lock>
>
> Have a good day.
> Paran Lee.
>
> Signed-off-by: Paran Lee <p4ranlee@gmail.com>
> ---
> fs/fs-writeback.c | 11 +++++++++--
> 1 file changed, 9 insertions(+), 2 deletions(-)
>
> diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c
> index 591fe9cf1659..23a7a567e443 100644
> --- a/fs/fs-writeback.c
> +++ b/fs/fs-writeback.c
> @@ -1357,12 +1357,14 @@ static int move_expired_inodes(struct list_head *delaying_queue,
> LIST_HEAD(tmp);
> struct list_head *pos, *node;
> struct super_block *sb = NULL;
> - struct inode *inode;
> + struct inode *inode = NULL;
> int do_sb_sort = 0;
> int moved = 0;
>
> while (!list_empty(delaying_queue)) {
> inode = wb_inode(delaying_queue->prev);
> + if(!inode)
> + continue;
> if (inode_dirtied_after(inode, dirtied_before))
> break;
> list_move(&inode->i_io_list, &tmp);
> @@ -1385,7 +1387,12 @@ static int move_expired_inodes(struct list_head *delaying_queue,
>
> /* Move inodes from one superblock together */
> while (!list_empty(&tmp)) {
> - sb = wb_inode(tmp.prev)->i_sb;
> + inode = wb_inode(tmp.prev);
> + if(!inode)
> + continue;
> + sb = inode->i_sb;
> + if(!sb)
> + continue;
> list_for_each_prev_safe(pos, node, &tmp) {
> inode = wb_inode(pos);
> if (inode->i_sb == sb)
> --
> 2.25.1
>
<formletter>
This is not the correct way to submit patches for inclusion in the
stable kernel tree. Please read:
https://www.kernel.org/doc/html/latest/process/stable-kernel-rules.html
for how to do this properly.
</formletter>
^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH] writeback: expired dirty inodes can lead to a NULL dereference kernel panic issue in 'move_expired_inodes' function
@ 2022-04-08 12:00 Paran Lee
2022-04-08 12:15 ` Matthew Wilcox
0 siblings, 1 reply; 5+ messages in thread
From: Paran Lee @ 2022-04-08 12:00 UTC (permalink / raw)
To: Jan Kara; +Cc: linux-fsdevel, Nicholas Piggin, Christoph Hellwig, Austin Kim
While tracing the null dereference kernel panic issue
during the stress-ng(stress-ng-proc) test,
I found the inode code block that could cause
a null dereference kernel panic.
BUG: unable to handle kernel NULL pointer dereference at 0000000000000008
inode stack variable not initialized and not check on this code block.
but find entry in delaying_queue. then, there was something suspicious
temp inode loop that could cause a kernel panic in below code block.
Signed-off-by: Paran Lee <p4ranlee@gmail.com>
---
fs/fs-writeback.c | 11 +++++++++--
1 file changed, 9 insertions(+), 2 deletions(-)
diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c
index 591fe9cf1659..23a7a567e443 100644
--- a/fs/fs-writeback.c
+++ b/fs/fs-writeback.c
@@ -1357,12 +1357,14 @@ static int move_expired_inodes(struct list_head *delaying_queue,
LIST_HEAD(tmp);
struct list_head *pos, *node;
struct super_block *sb = NULL;
- struct inode *inode;
+ struct inode *inode = NULL;
int do_sb_sort = 0;
int moved = 0;
while (!list_empty(delaying_queue)) {
inode = wb_inode(delaying_queue->prev);
+ if (!inode)
+ continue;
if (inode_dirtied_after(inode, dirtied_before))
break;
list_move(&inode->i_io_list, &tmp);
@@ -1385,7 +1387,12 @@ static int move_expired_inodes(struct list_head *delaying_queue,
/* Move inodes from one superblock together */
while (!list_empty(&tmp)) {
- sb = wb_inode(tmp.prev)->i_sb;
+ inode = wb_inode(tmp.prev);
+ if (!inode)
+ continue;
+ sb = inode->i_sb;
+ if (!sb)
+ continue;
list_for_each_prev_safe(pos, node, &tmp) {
inode = wb_inode(pos);
if (inode->i_sb == sb)
--
2.25.1
^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [PATCH] writeback: expired dirty inodes can lead to a NULL dereference kernel panic issue in 'move_expired_inodes' function
2022-04-08 12:00 Paran Lee
@ 2022-04-08 12:15 ` Matthew Wilcox
0 siblings, 0 replies; 5+ messages in thread
From: Matthew Wilcox @ 2022-04-08 12:15 UTC (permalink / raw)
To: Paran Lee
Cc: Jan Kara, linux-fsdevel, Nicholas Piggin, Christoph Hellwig,
Austin Kim
On Fri, Apr 08, 2022 at 09:00:01PM +0900, Paran Lee wrote:
> +++ b/fs/fs-writeback.c
> @@ -1357,12 +1357,14 @@ static int move_expired_inodes(struct list_head *delaying_queue,
> LIST_HEAD(tmp);
> struct list_head *pos, *node;
> struct super_block *sb = NULL;
> - struct inode *inode;
> + struct inode *inode = NULL;
Not needed; in fact I would move the definition of inode to inside the
while loop.
> int do_sb_sort = 0;
> int moved = 0;
>
> while (!list_empty(delaying_queue)) {
> inode = wb_inode(delaying_queue->prev);
> + if (!inode)
> + continue;
Did you look at the definition of wb_inode? It can't possibly return a
NULL pointer.
> /* Move inodes from one superblock together */
> while (!list_empty(&tmp)) {
> - sb = wb_inode(tmp.prev)->i_sb;
> + inode = wb_inode(tmp.prev);
> + if (!inode)
> + continue;
> + sb = inode->i_sb;
> + if (!sb)
> + continue;
Can you explain how inode might have a NULL i_sb?
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2022-04-08 12:15 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2022-04-08 7:18 [PATCH] writeback: expired dirty inodes can lead to a NULL dereference kernel panic issue in 'move_expired_inodes' function Paran Lee
2022-04-08 9:25 ` Colin King (gmail)
2022-04-08 11:25 ` Greg KH
-- strict thread matches above, loose matches on Subject: below --
2022-04-08 12:00 Paran Lee
2022-04-08 12:15 ` Matthew Wilcox
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.