Commit a28ef45cbb1e7fadd5159deb17b02de15c6e4aaf
1 parent
53ce9a3364
Exists in
master
and in
20 other branches
fuse: readdirplus: sanity checks
Add sanity checks before adding or updating an entry with data received from readdirplus. Signed-off-by: Miklos Szeredi <mszeredi@suse.cz> CC: stable@vger.kernel.org
Showing 1 changed file with 11 additions and 1 deletions Side-by-side Diff
fs/fuse/dir.c
... | ... | @@ -1223,6 +1223,12 @@ |
1223 | 1223 | if (name.name[1] == '.' && name.len == 2) |
1224 | 1224 | return 0; |
1225 | 1225 | } |
1226 | + | |
1227 | + if (invalid_nodeid(o->nodeid)) | |
1228 | + return -EIO; | |
1229 | + if (!fuse_valid_type(o->attr.mode)) | |
1230 | + return -EIO; | |
1231 | + | |
1226 | 1232 | fc = get_fuse_conn(dir); |
1227 | 1233 | |
1228 | 1234 | name.hash = full_name_hash(name.name, name.len); |
1229 | 1235 | |
... | ... | @@ -1231,10 +1237,14 @@ |
1231 | 1237 | inode = dentry->d_inode; |
1232 | 1238 | if (!inode) { |
1233 | 1239 | d_drop(dentry); |
1234 | - } else if (get_node_id(inode) != o->nodeid) { | |
1240 | + } else if (get_node_id(inode) != o->nodeid || | |
1241 | + ((o->attr.mode ^ inode->i_mode) & S_IFMT)) { | |
1235 | 1242 | err = d_invalidate(dentry); |
1236 | 1243 | if (err) |
1237 | 1244 | goto out; |
1245 | + } else if (is_bad_inode(inode)) { | |
1246 | + err = -EIO; | |
1247 | + goto out; | |
1238 | 1248 | } else { |
1239 | 1249 | struct fuse_inode *fi; |
1240 | 1250 | fi = get_fuse_inode(inode); |