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>] [day] [month] [year] [list]
Message-Id: <1415171357-32520-1-git-send-email-sh.yoon@lge.com>
Date:	Wed,  5 Nov 2014 16:09:17 +0900
From:	sh.yoon@....com
To:	miklos@...redi.hu
Cc:	xemul@...nvz.org, fuse-devel@...ts.sourceforge.net,
	linux-kernel@...r.kernel.org, seungho1.park@....com,
	iamyooon@...il.com, hyc.lee@...il.com, "sh.yoon" <sh.yoon@....com>
Subject: [PATCH] fuse : fix fuse writeback problem with O_WRONLY

From: "sh.yoon" <sh.yoon@....com>

With cache writeback turned on(kernel & library & user-fs),
writing to a file that is opened with O_WRONLY flag fails
to write and return EBADF error as below.

strace result :

open("/storage/emulated/legacy/tempfile.txt", O_WRONLY) = 3
write(3, "hello world\n\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 2048)
= -1 EBADF (Bad file number)

It is due to fuse_do_readpage( ) while writing a data
to page cache which isn't up-to-date.
For updating the page, fuse_do_readpage( ) tries to read
a page from a file which is opened with O_WRONLY flag

For example,
consider Ext4 is used for backend file system.
When we open a fuse file with O_WRONLY flag then
at the same time, a ext4 file would be opened with same flag
O_WRONLY.

But for writing, fuse cache writeback needs to read data
from the file in ext4 for updating fuse file page cache.
So fuse_do_read() function sends read request to fuse
library and let user-fs call read() from the ext4 file
which was opened with O_WRONLY flag.

refer to following sequence.

(1) generic_perform_write()
(2) fuse_write_begin()
(3) fuse_do_readpage()
(4) send read-request
(5) read() invoked by user-fs
(6) EBADF error occured

To resolve this problem,
when a fuse file is opened with O_WRONLY, changing backend-fs
open flag from O_WRONLY to O_RDWR could be a solution.
Because changed flag O_RDWR for user-fs would be used by fuse
file system internally, so O_WRONLY flag is still effective for
a user accesing through fuse file system.

Reported-by: hyunchul.lee <hyc.lee@...il.com>
Signed-off-by: sh.yoon <sh.yoon@....com>
---
 fs/fuse/file.c |   11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/fs/fuse/file.c b/fs/fuse/file.c
index caa8d95..f93b748 100644
--- a/fs/fuse/file.c
+++ b/fs/fuse/file.c
@@ -35,6 +35,17 @@ static int fuse_send_open(struct fuse_conn *fc, u64 nodeid, struct file *file,
 	inarg.flags = file->f_flags & ~(O_CREAT | O_EXCL | O_NOCTTY);
 	if (!fc->atomic_o_trunc)
 		inarg.flags &= ~O_TRUNC;
+
+	/*
+	 * If we open file with O_WRONLY flag,
+	 * page writeback would fail when reading a page is needed.
+	 * so it need to change O_WRONLY to O_RDWR.
+	 */
+	if ((inarg.flags & O_WRONLY) && fc->writeback_cache) {
+		inarg.flags &= ~O_WRONLY;
+		inarg.flags |= O_RDWR;
+	}
+
 	req->in.h.opcode = opcode;
 	req->in.h.nodeid = nodeid;
 	req->in.numargs = 1;
-- 
1.7.9.5

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ