fix
authorMiklos Szeredi <miklos@szeredi.hu>
Wed, 14 Dec 2005 22:16:28 +0000 (22:16 +0000)
committerMiklos Szeredi <miklos@szeredi.hu>
Wed, 14 Dec 2005 22:16:28 +0000 (22:16 +0000)
ChangeLog
kernel/dir.c
kernel/inode.c

index bd5245cd315d58ee29fc50c8ecb77dfdbac7f2a7..d5708538de1816ab8f0403cbbde68806c848e492 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -4,6 +4,9 @@
        without largefile support.  Bug report and help from Anthony
        Kolasny
 
+       * If lookup returns invalid mode, return -EIO instead of creating
+       a regular file.
+
 2005-12-12  Miklos Szeredi <miklos@szeredi.hu>
 
        * Fix stale code in ifdef FreeBSD.  Patch from Csaba Henk
index 8c161b6a133768951f8bdb31ae2494e476c7196a..b1bf3aa8042ee7d138acb801655d5a43e76be7e6 100644 (file)
@@ -190,6 +190,12 @@ static struct dentry_operations fuse_dentry_operations = {
 #endif
 };
 
+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)
 {
@@ -212,7 +218,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,
@@ -370,10 +377,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) {
@@ -382,8 +392,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;
        }
@@ -392,6 +401,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,
index 8c7c7d6a15b6f24ea4b47da9ebb16402afbcaf85..464a5199d2a71e89abfb3a9f0b92b2fd97597475 100644 (file)
@@ -160,12 +160,8 @@ static void fuse_init_inode(struct inode *inode, struct fuse_attr *attr)
                fuse_init_common(inode);
                init_special_inode(inode, inode->i_mode,
                                   new_decode_dev(attr->rdev));
-       } else {
-               /* Don't let user create weird files */
-               inode->i_mode = S_IFREG;
-               fuse_init_common(inode);
-               fuse_init_file_inode(inode);
-       }
+       } else
+               BUG();
 }
 
 #ifdef KERNEL_2_6