FAILED: patch "[PATCH] nilfs2: fix use-after-free of timer for log writer thread" failed to apply to 6.1-stable tree
Subsystems (2)
[email protected]
maintainerThe patch below does not apply to the 6.1-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.
To reproduce the conflict and resubmit, you may use the following commands:
git fetch https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/ linux-6.1.y
git checkout FETCH_HEAD
git cherry-pick -x f5d4e04634c9cf68bdf23de08ada0bb92e8befe7
# <resolve conflicts, build, test, etc.>
git commit -s
git send-email --to '<[email protected]>' --in-reply-to '2024052603-deceiving-stood-2b59@gregkh' --subject-prefix 'PATCH 6.1.y' HEAD^..
Possible dependencies:
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From f5d4e04634c9cf68bdf23de08ada0bb92e8befe7 Mon Sep 17 00:00:00 2001
From: Ryusuke Konishi <[email protected]>
Date: Mon, 20 May 2024 22:26:19 +0900
Subject: [PATCH] nilfs2: fix use-after-free of timer for log writer thread
Patch series "nilfs2: fix log writer related issues".
This bug fix series covers three nilfs2 log writer-related issues, including a timer use-after-free issue and potential deadlock issue on unmount, and a potential freeze issue in event synchronization found during their analysis. Details are described in each commit log.
This patch (of 3):
A use-after-free issue has been reported regarding the timer sc_timer on the nilfs_sc_info structure.
The problem is that even though it is used to wake up a sleeping log writer thread, sc_timer is not shut down until the nilfs_sc_info structure is about to be freed, and is used regardless of the thread's lifetime.
Fix this issue by limiting the use of sc_timer only while the log writer thread is alive.
fs/nilfs2/segment.c +19 -6
@@ -2118,8 +2118,10 @@ static void nilfs_segctor_start_timer(struct nilfs_sc_info *sci) {spin_lock (&sci->sc_state_lock);if (!(sci->sc_state &NILFS_SEGCTOR_COMMIT )) { - sci->sc_timer.expires = jiffies + sci->sc_interval; -add_timer (&sci->sc_timer); +if (sci->sc_task) { + sci->sc_timer.expires = jiffies + sci->sc_interval; +add_timer (&sci->sc_timer); + } sci->sc_state |=NILFS_SEGCTOR_COMMIT ; }spin_unlock (&sci->sc_state_lock);
@@ -2320,10 +2322,21 @@ int nilfs_construct_dsync_segment(struct super_block *sb, struct inode *inode,*/ static void nilfs_segctor_accept (struct nilfs_sc_info *sci) { +bool thread_is_alive; +spin_lock (&sci->sc_state_lock); sci->sc_seq_accepted = sci->sc_seq_request; + thread_is_alive = (bool )sci->sc_task;spin_unlock (&sci->sc_state_lock); -del_timer_sync (&sci->sc_timer); + +/* +* This function does not race with the log writer thread's +* termination. Therefore, deleting sc_timer, which should not be +* done after the log writer thread exits, can be done safely outside +* the area protected by sc_state_lock. +*/ +if (thread_is_alive) +del_timer_sync (&sci->sc_timer); }/**
@@ -2349,7 +2362,7 @@ static void nilfs_segctor_notify(struct nilfs_sc_info *sci, int mode, int err) sci->sc_flush_request &= ~FLUSH_DAT_BIT ;/* re-enable timer if checkpoint creation was not done */ -if ((sci->sc_state &NILFS_SEGCTOR_COMMIT ) && +if ((sci->sc_state &NILFS_SEGCTOR_COMMIT ) && sci->sc_task &&time_before (jiffies, sci->sc_timer.expires))add_timer (&sci->sc_timer); }
@@ -2539,6 +2552,7 @@ static int nilfs_segctor_thread(void *arg)int timeout =0 ; sci->sc_timer_task = current; +timer_setup (&sci->sc_timer, nilfs_construction_timeout,0 );/* start sync. */ sci->sc_task = current;
@@ -2606,6 +2620,7 @@ static int nilfs_segctor_thread(void *arg) end_thread:/* end sync. */ sci->sc_task =NULL ; +timer_shutdown_sync (&sci->sc_timer);wake_up (&sci->sc_wait_task);/* for nilfs_segctor_kill_thread() */ spin_unlock (&sci->sc_state_lock);return 0 ;
@@ -2669,7 +2684,6 @@ static struct nilfs_sc_info *nilfs_segctor_new(struct super_block *sb,INIT_LIST_HEAD (&sci->sc_gc_inodes);INIT_LIST_HEAD (&sci->sc_iput_queue);INIT_WORK (&sci->sc_iput_work, nilfs_iput_work_func); -timer_setup (&sci->sc_timer, nilfs_construction_timeout,0 ); sci->sc_interval =HZ *NILFS_SC_DEFAULT_TIMEOUT ; sci->sc_mjcp_freq =HZ *NILFS_SC_DEFAULT_SR_FREQ ;
@@ -2748,7 +2762,6 @@ static void nilfs_segctor_destroy(struct nilfs_sc_info *sci)down_write (&nilfs->ns_segctor_sem); -timer_shutdown_sync (&sci->sc_timer);kfree (sci); }
Ryusuke Konishi
maintainerPATCH 1/1 nilfs2: fix use-after-free of timer for log writer thread
commit f5d4e04634c9cf68bdf23de08ada0bb92e8befe7 upstream.
Patch series "nilfs2: fix log writer related issues".
This bug fix series covers three nilfs2 log writer-related issues, including a timer use-after-free issue and potential deadlock issue on unmount, and a potential freeze issue in event synchronization found during their analysis. Details are described in each commit log.
This patch (of 3):
A use-after-free issue has been reported regarding the timer sc_timer on the nilfs_sc_info structure.
The problem is that even though it is used to wake up a sleeping log writer thread, sc_timer is not shut down until the nilfs_sc_info structure is about to be freed, and is used regardless of the thread's lifetime.
Fix this issue by limiting the use of sc_timer only while the log writer thread is alive.
---
Please apply this patch to the stable trees indicated by the subject prefix instead of the patch that failed.
This patch is tailored to replace a call to timer_shutdown_sync(), which does not yet exist in these versions, with an equivalent function call, and is applicable from v4.15 to v6.1.
Also, all the builds and tests I did on each stable tree passed.
Thanks,
Ryusuke Konishi
fs/nilfs2/segment.c | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-)
fs/nilfs2/segment.c +19 -6
@@ -2159,8 +2159,10 @@ static void nilfs_segctor_start_timer(struct nilfs_sc_info *sci) {spin_lock (&sci->sc_state_lock);if (!(sci->sc_state &NILFS_SEGCTOR_COMMIT )) { - sci->sc_timer.expires = jiffies + sci->sc_interval; -add_timer (&sci->sc_timer); +if (sci->sc_task) { + sci->sc_timer.expires = jiffies + sci->sc_interval; +add_timer (&sci->sc_timer); + } sci->sc_state |=NILFS_SEGCTOR_COMMIT ; }spin_unlock (&sci->sc_state_lock);
@@ -2378,10 +2380,21 @@ int nilfs_construct_dsync_segment(struct super_block *sb, struct inode *inode,*/ static void nilfs_segctor_accept (struct nilfs_sc_info *sci) { +bool thread_is_alive; +spin_lock (&sci->sc_state_lock); sci->sc_seq_accepted = sci->sc_seq_request; + thread_is_alive = (bool )sci->sc_task;spin_unlock (&sci->sc_state_lock); -del_timer_sync (&sci->sc_timer); + +/* +* This function does not race with the log writer thread's +* termination. Therefore, deleting sc_timer, which should not be +* done after the log writer thread exits, can be done safely outside +* the area protected by sc_state_lock. +*/ +if (thread_is_alive) +del_timer_sync (&sci->sc_timer); }/**
@@ -2407,7 +2420,7 @@ static void nilfs_segctor_notify(struct nilfs_sc_info *sci, int mode, int err) sci->sc_flush_request &= ~FLUSH_DAT_BIT ;/* re-enable timer if checkpoint creation was not done */ -if ((sci->sc_state &NILFS_SEGCTOR_COMMIT ) && +if ((sci->sc_state &NILFS_SEGCTOR_COMMIT ) && sci->sc_task &&time_before (jiffies, sci->sc_timer.expires))add_timer (&sci->sc_timer); }
@@ -2597,6 +2610,7 @@ static int nilfs_segctor_thread(void *arg)int timeout =0 ; sci->sc_timer_task = current; +timer_setup (&sci->sc_timer, nilfs_construction_timeout,0 );/* start sync. */ sci->sc_task = current;
@@ -2663,6 +2677,7 @@ static int nilfs_segctor_thread(void *arg) end_thread:/* end sync. */ sci->sc_task =NULL ; +del_timer_sync (&sci->sc_timer);wake_up (&sci->sc_wait_task);/* for nilfs_segctor_kill_thread() */ spin_unlock (&sci->sc_state_lock);return 0 ;
@@ -2726,7 +2741,6 @@ static struct nilfs_sc_info *nilfs_segctor_new(struct super_block *sb,INIT_LIST_HEAD (&sci->sc_gc_inodes);INIT_LIST_HEAD (&sci->sc_iput_queue);INIT_WORK (&sci->sc_iput_work, nilfs_iput_work_func); -timer_setup (&sci->sc_timer, nilfs_construction_timeout,0 ); sci->sc_interval =HZ *NILFS_SC_DEFAULT_TIMEOUT ; sci->sc_mjcp_freq =HZ *NILFS_SC_DEFAULT_SR_FREQ ;
@@ -2812,7 +2826,6 @@ static void nilfs_segctor_destroy(struct nilfs_sc_info *sci)down_write (&nilfs->ns_segctor_sem); -del_timer_sync (&sci->sc_timer);kfree (sci); }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerRe: [PATCH 4.19 5.4 5.10 5.15 6.1] nilfs2: fix use-after-free of timer for log writer thread
Quoted 34 lines · Ryusuke Konishi
commit
f5d4e04634c9cf68bdf23de08ada0bb92e8befe7upstream.Patch series "nilfs2: fix log writer related issues".
This bug fix series covers three nilfs2 log writer-related issues, including a timer use-after-free issue and potential deadlock issue on unmount, and a potential freeze issue in event synchronization found during their analysis. Details are described in each commit log.
This patch (of 3):
A use-after-free issue has been reported regarding the timer
sc_timeron thenilfs_sc_infostructure.The problem is that even though it is used to wake up a sleeping log writer thread,
sc_timeris not shut down until thenilfs_sc_infostructure is about to be freed, and is used regardless of the thread's lifetime.Fix this issue by limiting the use of
sc_timeronly while the log writer thread is alive.Fixes fdce895ea5dd ("nilfs2: change sc_timer from a pointer to an embedded one in struct nilfs_sc_info")Signed-off-by Ryusuke Konishi <[email protected]>Reported-by "Bai, Shuangpeng" <[email protected]>Tested-by Ryusuke Konishi <[email protected]>Cc <[email protected]>Signed-off-by Andrew Morton <[email protected]>---
Please apply this patch to the stable trees indicated by the subject prefix instead of the patch that failed.
Quoted 5 lines
This patch is tailored to replace a call to
timer_shutdown_sync(), which does not yet exist in these versions, with an equivalent function call, and is applicable from v4.15 to v6.1.Also, all the builds and tests I did on each stable tree passed.
Now queued up, thanks.
greg k-h