I have found two problems around lookup a dir which is marked as opaque.
The first one is simple, just forgot DPUT() after failing
is_opaque_dir(). The second is rather nasty. When the dir is set as
unreadable, ie. the mode is 0700 or something, unionfs cannot detect it
is opaque or not. How about change the process's privilege temporally
when creating/searching/deleting the whiteouts.
While I am not sure this is the best, but here is the patch.


Junjiro Okajima


+ sudo ls -al ro/dir rw/dir
ro/dir:
total 2
drwx------  2 root jro 1024 Oct 27 01:36 .
drwxrwxrwx  8 jro  jro 1024 Oct 27 01:36 ..
-rw-r--r--  1 jro  jro    0 Oct 27 01:36 ro

rw/dir:
total 2
drwx------  2 root jro 1024 Oct 27 01:36 .
drwxrwxrwx  8 jro  jro 1024 Oct 27 01:36 ..
-rw-r--r--  1 jro  jro    0 Oct 27 01:36 .wh.__dir_opaque
-rw-r--r--  1 jro  jro    0 Oct 27 01:36 rw
+ sudo mount -t unionfs -o delete=whiteout,dirs=rw=rw:ro=ro none u

before patch,

+ ls -ald u/dir
ls: u/dir: Permission denied                    <-- incorrect
+ ls -al u/dir
ls: u/dir: Permission denied                    <-- correct
+ sudo ls -ald u/dir
drwx------  2 root jro 1024 Oct 27 01:36 u/dir
+ sudo ls -al u/dir
total 2
drwx------   2 root jro 1024 Oct 27 01:36 .
drwxrwxrwx  14 jro  jro 1024 Oct 27 01:36 ..
-rw-r--r--   1 jro  jro    0 Oct 27 01:36 rw
+ ls -ald u/dir
drwx------  2 root jro 1024 Oct 27 01:36 u/dir  <-- changed after 'sudo ls'
+ ls -al u/dir
ls: u/dir: Permission denied                    <-- correct

after patch,

+ ls -ald u/dir
drwx------  2 root jro 1024 Oct 27 01:43 u/dir
+ ls -al u/dir
ls: u/dir: Permission denied
+ sudo ls -ald u/dir
drwx------  2 root jro 1024 Oct 27 01:43 u/dir
+ sudo ls -al u/dir
total 2
drwx------   2 root jro 1024 Oct 27 01:43 .
drwxrwxrwx  14 jro  jro 1024 Oct 27 01:43 ..
-rw-r--r--   1 jro  jro    0 Oct 27 01:43 rw
+ ls -ald u/dir
drwx------  2 root jro 1024 Oct 27 01:43 u/dir
+ ls -al u/dir
ls: u/dir: Permission denied

----------------------------------------------------------------------
--- unionfs-20051025-2113/lookup.c.orig 2005-10-26 10:13:36.000000000 +0900
+++ unionfs-20051025-2113/lookup.c      2005-10-27 01:42:56.000000000 +0900
@@ -206,6 +206,7 @@ struct dentry *unionfs_lookup_backend(st
 
                opaque = is_opaque_dir(dentry, bindex);
                if (opaque < 0) {
+                       DPUT(first_hidden_dentry);
                        err = opaque;
                        goto out_free;
                }
@@ -335,17 +336,25 @@ static int is_opaque_dir(struct dentry *
        int err = 0;
        struct dentry *hidden_dentry;
        struct dentry *wh_hidden_dentry;
+       struct inode *hidden_inode;
+       uid_t saved_uid = current->fsuid;
+       gid_t saved_gid = current->fsgid;
 
        print_entry_location();
 
        hidden_dentry = dtohd_index(dentry, bindex);
 
        PASSERT(hidden_dentry);
-       PASSERT(hidden_dentry->d_inode);
-       ASSERT(S_ISDIR(hidden_dentry->d_inode->i_mode));
+       hidden_inode = hidden_dentry->d_inode;
+       PASSERT(hidden_inode);
+       ASSERT(S_ISDIR(hidden_inode->i_mode));
 
+       current->fsuid = hidden_inode->i_uid;
+       current->fsgid = hidden_inode->i_gid;
        wh_hidden_dentry = LOOKUP_ONE_LEN(UNIONFS_DIR_OPAQUE, hidden_dentry,
                                          sizeof(UNIONFS_DIR_OPAQUE) - 1);
+       current->fsuid = saved_uid;
+       current->fsgid = saved_gid;
        if (IS_ERR(wh_hidden_dentry)) {
                err = PTR_ERR(wh_hidden_dentry);
                fist_dprint(1, "LOOKUP_ONE_LEN returned: %d\n", err);
_______________________________________________
unionfs mailing list
[email protected]
http://www.fsl.cs.sunysb.edu/mailman/listinfo/unionfs

Reply via email to