| From a28ef45cbb1e7fadd5159deb17b02de15c6e4aaf Mon Sep 17 00:00:00 2001 |
| From: Miklos Szeredi <mszeredi@suse.cz> |
| Date: Wed, 17 Jul 2013 14:53:53 +0200 |
| Subject: fuse: readdirplus: sanity checks |
| |
| From: Miklos Szeredi <mszeredi@suse.cz> |
| |
| commit a28ef45cbb1e7fadd5159deb17b02de15c6e4aaf upstream. |
| |
| Add sanity checks before adding or updating an entry with data received |
| from readdirplus. |
| |
| Signed-off-by: Miklos Szeredi <mszeredi@suse.cz> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| |
| --- |
| fs/fuse/dir.c | 12 +++++++++++- |
| 1 file changed, 11 insertions(+), 1 deletion(-) |
| |
| --- a/fs/fuse/dir.c |
| +++ b/fs/fuse/dir.c |
| @@ -1225,6 +1225,12 @@ static int fuse_direntplus_link(struct f |
| if (name.name[1] == '.' && name.len == 2) |
| return 0; |
| } |
| + |
| + if (invalid_nodeid(o->nodeid)) |
| + return -EIO; |
| + if (!fuse_valid_type(o->attr.mode)) |
| + return -EIO; |
| + |
| fc = get_fuse_conn(dir); |
| |
| name.hash = full_name_hash(name.name, name.len); |
| @@ -1233,10 +1239,14 @@ static int fuse_direntplus_link(struct f |
| inode = dentry->d_inode; |
| if (!inode) { |
| d_drop(dentry); |
| - } else if (get_node_id(inode) != o->nodeid) { |
| + } else if (get_node_id(inode) != o->nodeid || |
| + ((o->attr.mode ^ inode->i_mode) & S_IFMT)) { |
| err = d_invalidate(dentry); |
| if (err) |
| goto out; |
| + } else if (is_bad_inode(inode)) { |
| + err = -EIO; |
| + goto out; |
| } else { |
| struct fuse_inode *fi; |
| fi = get_fuse_inode(inode); |