summaryrefslogtreecommitdiffstats
path: root/fs/fuse
diff options
context:
space:
mode:
authorMiklos Szeredi <miklos@szeredi.hu>2005-11-28 22:44:16 +0100
committerLinus Torvalds <torvalds@g5.osdl.org>2005-11-28 23:42:26 +0100
commitf007d5c961448170d0ec2998b1a80eef054b6235 (patch)
tree92f1d45fe8f2663e500fee1ddc8e5ea97cbc943f /fs/fuse
parent[PATCH] shrinker->nr = LONG_MAX means deadlock for icache (diff)
downloadlinux-f007d5c961448170d0ec2998b1a80eef054b6235.tar.xz
linux-f007d5c961448170d0ec2998b1a80eef054b6235.zip
[PATCH] fuse: check directory aliasing in mkdir
Check the created directory inode for aliases in the mkdir() method. Signed-off-by: Miklos Szeredi <miklos@szeredi.hu> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'fs/fuse')
-rw-r--r--fs/fuse/dir.c26
1 files changed, 17 insertions, 9 deletions
diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c
index c045cc70c749..3a47247a889e 100644
--- a/fs/fuse/dir.c
+++ b/fs/fuse/dir.c
@@ -74,6 +74,19 @@ static int fuse_dentry_revalidate(struct dentry *entry, struct nameidata *nd)
return 1;
}
+static int dir_alias(struct inode *inode)
+{
+ if (S_ISDIR(inode->i_mode)) {
+ /* Don't allow creating an alias to a directory */
+ struct dentry *alias = d_find_alias(inode);
+ if (alias) {
+ dput(alias);
+ return 1;
+ }
+ }
+ return 0;
+}
+
static struct dentry_operations fuse_dentry_operations = {
.d_revalidate = fuse_dentry_revalidate,
};
@@ -263,7 +276,7 @@ static int create_new_entry(struct fuse_conn *fc, struct fuse_req *req,
fuse_put_request(fc, req);
/* Don't allow userspace to do really stupid things... */
- if ((inode->i_mode ^ mode) & S_IFMT) {
+ if (((inode->i_mode ^ mode) & S_IFMT) || dir_alias(inode)) {
iput(inode);
return -EIO;
}
@@ -874,14 +887,9 @@ static struct dentry *fuse_lookup(struct inode *dir, struct dentry *entry,
err = fuse_lookup_iget(dir, entry, &inode);
if (err)
return ERR_PTR(err);
- if (inode && S_ISDIR(inode->i_mode)) {
- /* Don't allow creating an alias to a directory */
- struct dentry *alias = d_find_alias(inode);
- if (alias) {
- dput(alias);
- iput(inode);
- return ERR_PTR(-EIO);
- }
+ if (inode && dir_alias(inode)) {
+ iput(inode);
+ return ERR_PTR(-EIO);
}
d_add(entry, inode);
return NULL;