|
| 1 | +gfs2: Fix NULL pointer dereference in gfs2_log_flush |
| 2 | + |
| 3 | +jira LE-2157 |
| 4 | +cve CVE-2024-42079 |
| 5 | +Rebuild_History Non-Buildable kernel-5.14.0-503.14.1.el9_5 |
| 6 | +commit-author Andreas Gruenbacher <agruenba@redhat.com> |
| 7 | +commit 35264909e9d1973ab9aaa2a1b07cda70f12bb828 |
| 8 | +Empty-Commit: Cherry-Pick Conflicts during history rebuild. |
| 9 | +Will be included in final tarball splat. Ref for failed cherry-pick at: |
| 10 | +ciq/ciq_backports/kernel-5.14.0-503.14.1.el9_5/35264909.failed |
| 11 | + |
| 12 | +In gfs2_jindex_free(), set sdp->sd_jdesc to NULL under the log flush |
| 13 | +lock to provide exclusion against gfs2_log_flush(). |
| 14 | + |
| 15 | +In gfs2_log_flush(), check if sdp->sd_jdesc is non-NULL before |
| 16 | +dereferencing it. Otherwise, we could run into a NULL pointer |
| 17 | +dereference when outstanding glock work races with an unmount |
| 18 | +(glock_work_func -> run_queue -> do_xmote -> inode_go_sync -> |
| 19 | +gfs2_log_flush). |
| 20 | + |
| 21 | + Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com> |
| 22 | +(cherry picked from commit 35264909e9d1973ab9aaa2a1b07cda70f12bb828) |
| 23 | + Signed-off-by: Jonathan Maple <jmaple@ciq.com> |
| 24 | + |
| 25 | +# Conflicts: |
| 26 | +# fs/gfs2/log.c |
| 27 | +diff --cc fs/gfs2/log.c |
| 28 | +index fd86c9f54bf4,a6dd68b458ce..000000000000 |
| 29 | +--- a/fs/gfs2/log.c |
| 30 | ++++ b/fs/gfs2/log.c |
| 31 | +@@@ -1097,13 -1103,14 +1097,19 @@@ repeat |
| 32 | + goto out_withdraw; |
| 33 | + |
| 34 | + gfs2_ordered_write(sdp); |
| 35 | + - if (gfs2_withdrawing_or_withdrawn(sdp)) |
| 36 | + + if (gfs2_withdrawn(sdp)) |
| 37 | + goto out_withdraw; |
| 38 | + lops_before_commit(sdp, tr); |
| 39 | + - if (gfs2_withdrawing_or_withdrawn(sdp)) |
| 40 | + + if (gfs2_withdrawn(sdp)) |
| 41 | + goto out_withdraw; |
| 42 | +++<<<<<<< HEAD |
| 43 | + + gfs2_log_submit_bio(&sdp->sd_jdesc->jd_log_bio, REQ_OP_WRITE); |
| 44 | + + if (gfs2_withdrawn(sdp)) |
| 45 | +++======= |
| 46 | ++ if (sdp->sd_jdesc) |
| 47 | ++ gfs2_log_submit_bio(&sdp->sd_jdesc->jd_log_bio, REQ_OP_WRITE); |
| 48 | ++ if (gfs2_withdrawing_or_withdrawn(sdp)) |
| 49 | +++>>>>>>> 35264909e9d1 (gfs2: Fix NULL pointer dereference in gfs2_log_flush) |
| 50 | + goto out_withdraw; |
| 51 | + |
| 52 | + if (sdp->sd_log_head != sdp->sd_log_flush_head) { |
| 53 | +* Unmerged path fs/gfs2/log.c |
| 54 | +diff --git a/fs/gfs2/super.c b/fs/gfs2/super.c |
| 55 | +index e7843110531e..1b16abc441c2 100644 |
| 56 | +--- a/fs/gfs2/super.c |
| 57 | ++++ b/fs/gfs2/super.c |
| 58 | +@@ -67,9 +67,13 @@ void gfs2_jindex_free(struct gfs2_sbd *sdp) |
| 59 | + sdp->sd_journals = 0; |
| 60 | + spin_unlock(&sdp->sd_jindex_spin); |
| 61 | + |
| 62 | ++ down_write(&sdp->sd_log_flush_lock); |
| 63 | + sdp->sd_jdesc = NULL; |
| 64 | ++ up_write(&sdp->sd_log_flush_lock); |
| 65 | ++ |
| 66 | + while (!list_empty(&list)) { |
| 67 | + jd = list_first_entry(&list, struct gfs2_jdesc, jd_list); |
| 68 | ++ BUG_ON(jd->jd_log_bio); |
| 69 | + gfs2_free_journal_extents(jd); |
| 70 | + list_del(&jd->jd_list); |
| 71 | + iput(jd->jd_inode); |
0 commit comments