lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-ID: <20241023135850067m3w2R0UXESiVCYz_wdAoT@zte.com.cn>
Date: Wed, 23 Oct 2024 13:58:50 +0800 (CST)
From: <shao.mingyin@....com.cn>
To: <viro@...iv.linux.org.uk>, <brauner@...nel.org>, <jack@...e.cz>,
        <linux-fsdevel@...r.kernel.org>, <linux-kernel@...r.kernel.org>
Cc: <yang.yang29@....com.cn>, <yang.tao172@....com.cn>, <xu.xin16@....com.cn>,
        <lu.zhongjun@....com.cn>, <chen.lin5@....com.cn>
Subject: [PATCH] fs: fix bug that fput() may not have done to complete in

 flush_delayed_fput

From: shao mingyin <shao.mingyin@....com.cn>

We find a bug that the rcS file may not be executed, resulting in module 
and business not being loaded. When trying to execute rcS, the fput() 
related to rcS has not done to complete, so deny_write_access() returns 
ETXTBSY.

rcS is opened in do_populate_rootfs before executed.
After flush_delayed_fput() has done to complete, do_populate_rootfs 
assumes that all fput() related to do_populate_rootfs has done to complete.
However, flush_delayed_fput can only ensure that the fput() on current 
delayed_fput_list has done to complete, the fput() that has already been 
removed from delayed_fput_list in advance may not be completed. Attempting
to execute the file associated with this fput() now will result in ETXTBSY.
Most of the time, the fput() related to rcS has done to complete in 
do_populate_rootfs before executing rcS, but sometimes it's not.

do_populate_rootfs	delayed_fput_list	delayed_fput	execve
fput()			a
fput()			a->b
fput()			a->b->rcS
						__fput(a)
fput()			c
fput()			c->d
						__fput(b)
flush_delayed_fput
__fput(c)
__fput(d)
						__fput(b)
						__fput(b)	execve(rcS)

in execve(rcS), deny_write_access(rcS) returns ETXTBSY because __fput(rcS) 
has not done to complete.

This patch can guarantee all fput() related to do_populate_rootfs has done 
to complete, and ensure that rcS can be executed successfully.

Signed-off-by: Chen Lin <chen.lin5@....com.cn>
Signed-off-by: Shao Mingyin <shao.mingyin@....com.cn>
Cc: Yang Yang <yang.yang29@....com.cn>
Cc: Yang Tao <yang.tao172@....com.cn>
Cc: Xu Xin <xu.xin16@....com.cn>
---
 fs/file_table.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/fs/file_table.c b/fs/file_table.c
index eed5ffad9997..345e68caa4d7 100644
--- a/fs/file_table.c
+++ b/fs/file_table.c
@@ -462,6 +462,8 @@ static void ____fput(struct callback_head *work)
 	__fput(container_of(work, struct file, f_task_work));
 }

+static DECLARE_DELAYED_WORK(delayed_fput_work, delayed_fput);
+
 /*
  * If kernel thread really needs to have the final fput() it has done
  * to complete, call this.  The only user right now is the boot - we
@@ -475,11 +477,10 @@ static void ____fput(struct callback_head *work)
 void flush_delayed_fput(void)
 {
 	delayed_fput(NULL);
+	flush_delayed_work(&delayed_fput_work);
 }
 EXPORT_SYMBOL_GPL(flush_delayed_fput);

-static DECLARE_DELAYED_WORK(delayed_fput_work, delayed_fput);
-
 void fput(struct file *file)
 {
 	if (file_ref_put(&file->f_ref)) {
-- 
2.25.1

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ