2012-08-15 13:58:45

by Miklos Szeredi

[permalink] [raw]
Subject: [PATCH 0/4] vfs: fix file creation mode bugs

This fixes a FUSE regression reported against 3.6-rc1 as well as an older bug
(stable CC-d).

Please apply.

Thanks,
Miklos


---
Miklos Szeredi (4):
vfs: canonicalize create mode in build_open_flags()
vfs: atomic_open(): fix create mode usage
vfs: pass right create mode to may_o_create()
fuse: check create mode in atomic open

---
fs/fuse/dir.c | 3 +++
fs/namei.c | 4 ++--
fs/open.c | 7 ++++---
3 files changed, 9 insertions(+), 5 deletions(-)


2012-08-15 13:58:56

by Miklos Szeredi

[permalink] [raw]
Subject: [PATCH 3/4] vfs: pass right create mode to may_o_create()

From: Miklos Szeredi <[email protected]>

Pass the umask-ed create mode to may_o_create() instead of the original one.

Signed-off-by: Miklos Szeredi <[email protected]>
Tested-by: Richard W.M. Jones <[email protected]>
---
fs/namei.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/fs/namei.c b/fs/namei.c
index 5bac1bb..26c28ec 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -2452,7 +2452,7 @@ static int atomic_open(struct nameidata *nd, struct dentry *dentry,
}

if (open_flag & O_CREAT) {
- error = may_o_create(&nd->path, dentry, op->mode);
+ error = may_o_create(&nd->path, dentry, mode);
if (error) {
create_error = error;
if (open_flag & O_EXCL)
--
1.7.7

2012-08-15 13:59:01

by Miklos Szeredi

[permalink] [raw]
Subject: [PATCH 4/4] fuse: check create mode in atomic open

From: Miklos Szeredi <[email protected]>

Verify that the VFS is passing us a complete create mode with the S_IFREG to
atomic open.

Reported-by: Steve <[email protected]>
Reported-by: Richard W.M. Jones <[email protected]>
Signed-off-by: Miklos Szeredi <[email protected]>
Tested-by: Richard W.M. Jones <[email protected]>
---
fs/fuse/dir.c | 3 +++
1 files changed, 3 insertions(+), 0 deletions(-)

diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c
index 8964cf3..324bc08 100644
--- a/fs/fuse/dir.c
+++ b/fs/fuse/dir.c
@@ -383,6 +383,9 @@ static int fuse_create_open(struct inode *dir, struct dentry *entry,
struct fuse_entry_out outentry;
struct fuse_file *ff;

+ /* Userspace expects S_IFREG in create mode */
+ BUG_ON((mode & S_IFMT) != S_IFREG);
+
forget = fuse_alloc_forget();
err = -ENOMEM;
if (!forget)
--
1.7.7

2012-08-15 13:58:53

by Miklos Szeredi

[permalink] [raw]
Subject: [PATCH 1/4] vfs: canonicalize create mode in build_open_flags()

From: Miklos Szeredi <[email protected]>

Userspace can pass weird create mode in open(2) that we canonicalize to
"(mode & S_IALLUGO) | S_IFREG" in vfs_create().

The problem is that we use the uncanonicalized mode before calling vfs_create()
with unforseen consequences.

So do the canonicalization early in build_open_flags().

Signed-off-by: Miklos Szeredi <[email protected]>
Tested-by: Richard W.M. Jones <[email protected]>
CC: [email protected]
---
fs/open.c | 7 ++++---
1 files changed, 4 insertions(+), 3 deletions(-)

diff --git a/fs/open.c b/fs/open.c
index bc132e1..e1f2cdb 100644
--- a/fs/open.c
+++ b/fs/open.c
@@ -852,9 +852,10 @@ static inline int build_open_flags(int flags, umode_t mode, struct open_flags *o
int lookup_flags = 0;
int acc_mode;

- if (!(flags & O_CREAT))
- mode = 0;
- op->mode = mode;
+ if (flags & O_CREAT)
+ op->mode = (mode & S_IALLUGO) | S_IFREG;
+ else
+ op->mode = 0;

/* Must never be set by userspace */
flags &= ~FMODE_NONOTIFY;
--
1.7.7

2012-08-15 14:00:01

by Miklos Szeredi

[permalink] [raw]
Subject: [PATCH 2/4] vfs: atomic_open(): fix create mode usage

From: Miklos Szeredi <[email protected]>

Don't mask S_ISREG off the create mode before passing to ->atomic_open(). Other
methods (->create, ->mknod) also get the complete file mode and filesystems
expect it.

Reported-by: Steve <[email protected]>
Reported-by: Richard W.M. Jones <[email protected]>
Signed-off-by: Miklos Szeredi <[email protected]>
Tested-by: Richard W.M. Jones <[email protected]>
---
fs/namei.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/fs/namei.c b/fs/namei.c
index 1b46439..5bac1bb 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -2414,7 +2414,7 @@ static int atomic_open(struct nameidata *nd, struct dentry *dentry,
goto out;
}

- mode = op->mode & S_IALLUGO;
+ mode = op->mode;
if ((open_flag & O_CREAT) && !IS_POSIXACL(dir))
mode &= ~current_umask();

--
1.7.7