diff mbox series

fix "NULL pointer dereference in gfs2_recover_func"

Message ID 20250218093003.41966-1-chunjie.zhu@cloud.com (mailing list archive)
State New
Headers show
Series fix "NULL pointer dereference in gfs2_recover_func" | expand

Checks

Context Check Description
netdev/tree_selection success Not a local patch

Commit Message

Chunjie Zhu Feb. 18, 2025, 9:30 a.m. UTC
During gfs2_withdraw, sdp->sd_jdesc->jd_inode might be NULL, in
  gfs2_recover_func, we should first check WITHDRAW flag, then do
  gfs2_inode and gfs2_sbd variable reference, otherwise, we might
  run into kernel panic

  I/O error, dev sdc, sector 125744 op 0x1:(WRITE) flags 0x4200 phys_seg 4 prio class 2
  I/O error, dev dm-1, sector 125776 op 0x1:(WRITE) flags 0x21800 phys_seg 1 prio class 2
  gfs2: fsid=xapi-clusterd:760b13b0-d513-03.1: Error 10 writing to journal, jid=1
  I/O error, dev dm-1, sector 125744 op 0x1:(WRITE) flags 0x0 phys_seg 4 prio class 2
  gfs2: fsid=xapi-clusterd:760b13b0-d513-03.1: about to withdraw this file system
  gfs2: fsid=xapi-clusterd:760b13b0-d513-03.1: recover_prep ignored due to withdraw.
  gfs2: fsid=xapi-clusterd:760b13b0-d513-03.1: recover_done ignored due to withdraw.
  BUG: kernel NULL pointer dereference, address: 0000000000000028
  #PF: supervisor read access in kernel mode
  #PF: error_code(0x0000) - not-present page
  PGD 0 P4D 0
  Oops: 0000 [#1] SMP NOPTI
  CPU: 15 PID: 614 Comm: kworker/15:4 Not tainted 6.6.22+0 #1
  Hardware name: Dell Inc. PowerEdge C6615/0V93MP, BIOS 1.2.3 12/19/2023
  Workqueue: gfs2_recovery gfs2_recover_func [gfs2]
  RIP: e030:gfs2_recover_func+0x3e/0xb90 [gfs2]
  Code: 89 e5 41 57 41 56 41 55 41 54 41 52 53 48 89 fb 48 81 ec 70 01 00 00 4c 8b 77 20 65 48 8b 04 25 28 00 00 00 48 89 45 c8 31 c0 <49> 8b 46 28 4c 8b a0 70 03 00 00 49 8b 44 24 70 a8 04 75 0a 49 8b
  RSP: e02b:ffffc90040acfcb0 EFLAGS: 00010246
  RAX: 0000000000000000 RBX: ffff8881047a7a68 RCX: ffff88821a7ee9a8
  RDX: 0000000000000001 RSI: 8080808080808080 RDI: ffff8881047a7a68
  RBP: ffffc90040acfe50 R08: 6264715e31726566 R09: ffff888103df9400
  R10: ffffc90040acfe70 R11: fefefefefefefeff R12: ffff88814a0a9600
  R13: ffff88821a7ee980 R14: 0000000000000000 R15: ffff88812b300eb0
  FS:  0000000000000000(0000) GS:ffff88821a7c0000(0000) knlGS:0000000000000000
  CS:  e030 DS: 0000 ES: 0000 CR0: 0000000080050033
  CR2: 0000000000000028 CR3: 0000000153dfc000 CR4: 0000000000050660
  Call Trace:
   <TASK>
   ? __die+0x1f/0x70
   ? page_fault_oops+0x159/0x440
   ? search_bpf_extables+0xe/0x60
   ? srso_alias_return_thunk+0x5/0x7f
   ? fixup_exception+0x22/0x300
   ? srso_alias_return_thunk+0x5/0x7f
   ? exc_page_fault+0x6d/0x130
   ? asm_exc_page_fault+0x22/0x30
   ? gfs2_recover_func+0x3e/0xb90 [gfs2]
   ? srso_alias_return_thunk+0x5/0x7f
   ? xen_extend_mmuext_op+0x1e/0xc0
   ? srso_alias_return_thunk+0x5/0x7f
   ? srso_alias_return_thunk+0x5/0x7f
   ? update_load_avg+0x7a/0x720
   ? srso_alias_return_thunk+0x5/0x7f
   ? pmu_msr_read+0x38/0xd0
   ? psi_group_change+0x152/0x3d0
   ? xen_mc_flush+0x15f/0x1f0
   ? srso_alias_return_thunk+0x5/0x7f
   ? srso_alias_return_thunk+0x5/0x7f
   ? xen_load_sp0+0x33/0x80
   ? srso_alias_return_thunk+0x5/0x7f
   ? srso_alias_return_thunk+0x5/0x7f
   ? finish_task_switch.isra.0+0x85/0x240
   ? srso_alias_return_thunk+0x5/0x7f
   ? __schedule+0x3a8/0x1330
   ? srso_alias_return_thunk+0x5/0x7f
   ? page_counter_uncharge+0x2f/0x70
   ? process_one_work+0x168/0x310
   ? __pfx_gfs2_recover_func+0x10/0x10 [gfs2]
   process_one_work+0x168/0x310
   worker_thread+0x2f8/0x410
   ? __pfx_worker_thread+0x10/0x10
   kthread+0xcc/0x100
   ? __pfx_kthread+0x10/0x10
   ret_from_fork+0x30/0x50
   ? __pfx_kthread+0x10/0x10
   ret_from_fork_asm+0x1b/0x30
   </TASK>

Signed-off-by: Chunjie Zhu <chunjie.zhu@cloud.com>
---
 fs/gfs2/recovery.c | 11 ++++++++---
 1 file changed, 8 insertions(+), 3 deletions(-)
diff mbox series

Patch

diff --git a/fs/gfs2/recovery.c b/fs/gfs2/recovery.c
index 5aae02669a40..44806513fc06 100644
--- a/fs/gfs2/recovery.c
+++ b/fs/gfs2/recovery.c
@@ -400,9 +400,9 @@  static void recover_local_statfs(struct gfs2_jdesc *jd,
 
 void gfs2_recover_func(struct work_struct *work)
 {
-	struct gfs2_jdesc *jd = container_of(work, struct gfs2_jdesc, jd_work);
-	struct gfs2_inode *ip = GFS2_I(jd->jd_inode);
-	struct gfs2_sbd *sdp = GFS2_SB(jd->jd_inode);
+	struct gfs2_jdesc *jd = NULL;
+	struct gfs2_inode *ip = NULL;
+	struct gfs2_sbd *sdp = NULL;
 	struct gfs2_log_header_host head;
 	struct gfs2_holder j_gh, ji_gh;
 	ktime_t t_start, t_jlck, t_jhd, t_tlck, t_rep;
@@ -416,6 +416,11 @@  void gfs2_recover_func(struct work_struct *work)
 		       jd->jd_jid);
 		goto fail;
 	}
+
+	jd = container_of(work, struct gfs2_jdesc, jd_work);
+	ip = GFS2_I(jd->jd_inode);
+	sdp = GFS2_SB(jd->jd_inode);
+
 	t_start = ktime_get();
 	if (sdp->sd_args.ar_spectator)
 		goto fail;