]> err.no Git - linux-2.6/blobdiff - fs/fuse/dir.c
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/roland...
[linux-2.6] / fs / fuse / dir.c
index 9a6075de961fb2eee09d84b7a42d373ebb2a0154..417bcee466f660dc7396c492d6ac1dd93ed054bb 100644 (file)
@@ -166,6 +166,12 @@ static struct dentry_operations fuse_dentry_operations = {
        .d_revalidate   = fuse_dentry_revalidate,
 };
 
+static inline int valid_mode(int m)
+{
+       return S_ISREG(m) || S_ISDIR(m) || S_ISLNK(m) || S_ISCHR(m) ||
+               S_ISBLK(m) || S_ISFIFO(m) || S_ISSOCK(m);
+}
+
 static struct dentry *fuse_lookup(struct inode *dir, struct dentry *entry,
                                  struct nameidata *nd)
 {
@@ -185,7 +191,8 @@ static struct dentry *fuse_lookup(struct inode *dir, struct dentry *entry,
        fuse_lookup_init(req, dir, entry, &outarg);
        request_send(fc, req);
        err = req->out.h.error;
-       if (!err && outarg.nodeid && invalid_nodeid(outarg.nodeid))
+       if (!err && ((outarg.nodeid && invalid_nodeid(outarg.nodeid)) ||
+                    !valid_mode(outarg.attr.mode)))
                err = -EIO;
        if (!err && outarg.nodeid) {
                inode = fuse_iget(dir->i_sb, outarg.nodeid, outarg.generation,
@@ -236,10 +243,6 @@ static int fuse_create_open(struct inode *dir, struct dentry *entry, int mode,
        if (fc->no_create)
                goto out;
 
-       err = -ENAMETOOLONG;
-       if (entry->d_name.len > FUSE_NAME_MAX)
-               goto out;
-
        err = -EINTR;
        req = fuse_get_request(fc);
        if (!req)
@@ -332,10 +335,13 @@ static int create_new_entry(struct fuse_conn *fc, struct fuse_req *req,
                fuse_put_request(fc, req);
                return err;
        }
-       if (invalid_nodeid(outarg.nodeid)) {
-               fuse_put_request(fc, req);
-               return -EIO;
-       }
+       err = -EIO;
+       if (invalid_nodeid(outarg.nodeid))
+               goto out_put_request;
+
+       if ((outarg.attr.mode ^ mode) & S_IFMT)
+               goto out_put_request;
+
        inode = fuse_iget(dir->i_sb, outarg.nodeid, outarg.generation,
                          &outarg.attr);
        if (!inode) {
@@ -344,8 +350,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) || dir_alias(inode)) {
+       if (dir_alias(inode)) {
                iput(inode);
                return -EIO;
        }
@@ -354,6 +359,10 @@ static int create_new_entry(struct fuse_conn *fc, struct fuse_req *req,
        fuse_change_timeout(entry, &outarg);
        fuse_invalidate_attr(dir);
        return 0;
+
+ out_put_request:
+       fuse_put_request(fc, req);
+       return err;
 }
 
 static int fuse_mknod(struct inode *dir, struct dentry *entry, int mode,
@@ -413,12 +422,7 @@ static int fuse_symlink(struct inode *dir, struct dentry *entry,
 {
        struct fuse_conn *fc = get_fuse_conn(dir);
        unsigned len = strlen(link) + 1;
-       struct fuse_req *req;
-
-       if (len > FUSE_SYMLINK_MAX)
-               return -ENAMETOOLONG;
-
-       req = fuse_get_request(fc);
+       struct fuse_req *req = fuse_get_request(fc);
        if (!req)
                return -EINTR;
 
@@ -988,9 +992,6 @@ static int fuse_setxattr(struct dentry *entry, const char *name,
        struct fuse_setxattr_in inarg;
        int err;
 
-       if (size > FUSE_XATTR_SIZE_MAX)
-               return -E2BIG;
-
        if (fc->no_setxattr)
                return -EOPNOTSUPP;