Now ls works correctly inside a userns!

(but don't go doing some sort of setattr like 'chown'  :)

Signed-off-by: Serge Hallyn <[EMAIL PROTECTED]>
---
 fs/ext3/file.c  |    4 ++++
 fs/ext3/inode.c |   22 ++++++++++++++++++++++
 fs/ext3/namei.c |    3 +++
 fs/ext3/xattr.c |    6 ++++++
 lib/fsuserns.c  |   42 +++++++++++++++++++++++++++++-------------
 5 files changed, 64 insertions(+), 13 deletions(-)

diff --git a/fs/ext3/file.c b/fs/ext3/file.c
index acc4913..b259061 100644
--- a/fs/ext3/file.c
+++ b/fs/ext3/file.c
@@ -106,6 +106,9 @@ force_commit:
        return ret;
 }
 
+extern int ext3_getattr(struct vfsmount *mnt, struct dentry *dentry,
+                                       struct kstat *stat);
+
 const struct file_operations ext3_file_operations = {
        .llseek         = generic_file_llseek,
        .read           = do_sync_read,
@@ -134,5 +137,6 @@ const struct inode_operations ext3_file_inode_operations = {
        .removexattr    = generic_removexattr,
 #endif
        .permission     = ext3_permission,
+       .getattr        = ext3_getattr,
 };
 
diff --git a/fs/ext3/inode.c b/fs/ext3/inode.c
index 507d868..b252490 100644
--- a/fs/ext3/inode.c
+++ b/fs/ext3/inode.c
@@ -36,6 +36,7 @@
 #include <linux/mpage.h>
 #include <linux/uio.h>
 #include <linux/bio.h>
+#include <linux/security.h>
 #include "xattr.h"
 #include "acl.h"
 
@@ -3088,6 +3089,27 @@ err_out:
        return error;
 }
 
+int ext3_getattr(struct vfsmount *mnt, struct dentry *dentry,
+                                       struct kstat *stat)
+{
+       struct inode *inode = dentry->d_inode;
+       int retval;
+       uid_t uid;
+       gid_t gid;
+
+       retval = security_inode_getattr(mnt, dentry);
+       if (retval)
+               return retval;
+
+       generic_fillattr(inode, stat);
+
+       retval = s_convert_uid_gid(inode, current->user->user_ns, &uid, &gid);
+       if (retval == 1) {
+               stat->uid = uid;
+               stat->gid = gid;
+       }
+       return 0;
+}
 
 /*
  * How many blocks doth make a writepage()?
diff --git a/fs/ext3/namei.c b/fs/ext3/namei.c
index e5be4bc..fe7350b 100644
--- a/fs/ext3/namei.c
+++ b/fs/ext3/namei.c
@@ -2410,6 +2410,8 @@ end_rename:
        return retval;
 }
 
+extern int ext3_getattr(struct vfsmount *mnt, struct dentry *dentry,
+                                       struct kstat *stat);
 /*
  * directories can handle most operations...
  */
@@ -2431,6 +2433,7 @@ const struct inode_operations ext3_dir_inode_operations = 
{
        .removexattr    = generic_removexattr,
 #endif
        .permission     = ext3_permission,
+       .getattr        = ext3_getattr,
 };
 
 const struct inode_operations ext3_special_inode_operations = {
diff --git a/fs/ext3/xattr.c b/fs/ext3/xattr.c
index 500fec7..cf7dc63 100644
--- a/fs/ext3/xattr.c
+++ b/fs/ext3/xattr.c
@@ -345,6 +345,7 @@ ext3_xattr_get_userns(struct inode *inode, void *value, 
size_t value_size)
                error = ext3_xattr_block_get(inode, name_index, name, value,
                                             value_size);
        up_read(&EXT3_I(inode)->xattr_sem);
+       printk(KERN_NOTICE "%s: returning %d for %lu\n", __func__, error, 
inode->i_ino);
        return error;
 }
 
@@ -1102,7 +1103,12 @@ retry:
                error = PTR_ERR(handle);
        } else {
                int error2;
+               char *buf;
+               int i;
 
+               printk(KERN_NOTICE "%s: writing %d bytes:\n", __func__, 
value_len);
+               for (i=0, buf = (char *)value; i<value_len; i++,buf++)
+                       printk(KERN_NOTICE "%s: %d %x\n", __func__, i, 
(int)*buf);
                error = ext3_xattr_set_handle(handle, inode, name_index, name,
                                              value, value_len, 0);
                error2 = ext3_journal_stop(handle);
diff --git a/lib/fsuserns.c b/lib/fsuserns.c
index ac0ca99..f0be780 100644
--- a/lib/fsuserns.c
+++ b/lib/fsuserns.c
@@ -179,7 +179,7 @@ int fsuserns_convert_uid_gid(struct user_namespace *ns, 
struct inode *inode,
        struct fsuserns_conversion_table *t;
        struct fsuserns_table_entries *ep;
        size_t valuelen;
-       struct unsstore *unsstore;
+       struct unsstore *unsstore = NULL;
        int i, ret;
 
        t = find_table(sb);
@@ -196,23 +196,33 @@ int fsuserns_convert_uid_gid(struct user_namespace *ns, 
struct inode *inode,
 convert:
        mutex_unlock(&fsuserns_table_mutex);
 
-       /* look for an xattr */
-       /* yes, 3 needs to be made adjustable */
-       valuelen = 3;
-       unsstore = kzalloc(3*sizeof(struct unsstore), GFP_KERNEL);
+       ret = xattrget(inode, NULL, 0);
+       if (ret <= 0)
+               goto notfound;
+       valuelen = ret;
+       unsstore = kzalloc(ret, GFP_KERNEL);
        ret = xattrget(inode, unsstore, valuelen);
-       if (ret < 0)
-               return ret;
-       for (i=0; i<3; i++)
+       if (ret <= 0)
+               goto notfound;
+       for (i=0; i<(ret/sizeof(*unsstore)); i++) {
+               printk(KERN_NOTICE "%s: comparing unstore id %d to userns id 
%d\n",
+                       __func__, unsstore[i].ns, ep->userns_id);
                if (unsstore[i].ns == ep->userns_id)
-                       break;
-       if (i==3)
-               goto out;
+                       goto found;
+       }
+       goto notfound;
+
+found:
        *retuid = unsstore[i].uid;
        *retgid = unsstore[i].gid;
+       printk(KERN_NOTICE "%s: found a uid (%d) for nsid %d\n",
+                       __func__, *retuid, ep->userns_id);
+       kfree(unsstore);
        return 1;
 
-out:
+notfound:
+       kfree(unsstore);
+       printk(KERN_NOTICE "%s: no uid for my ns found\n", __func__);
        /* The following is BAD CODE.  IT's for testing only */
        if (current->uid == 0) {
                if (inode->i_uid == ns->creator->uid) {
@@ -291,6 +301,12 @@ found:
 
 }
 
+/*
+ * Let's say uid 500 in the init_user_ns created (nsid=3), and uid 400
+ * there created (nsid=5).  Then root in nsid=5 creates a file.
+ * We want to store 500 as the inode->iuid.  In xattr security.userns
+ * we store (3,400) and (5,0)
+ */
 int fsuserns_store_creds(struct inode *inode, struct user_struct *user,
        int (*xattrset)(struct inode *inode, const void *value, size_t 
value_len))
 {
@@ -327,7 +343,7 @@ int fsuserns_store_creds(struct inode *inode, struct 
user_struct *user,
                        unsstore[i].gid = current->gid;
                else
                        unsstore[i].gid = lastns->creator_grp;
-               printk(KERN_NOTICE "%s: setting xattr with ns=%d,uid=%d\n", 
__func__,
+               printk(KERN_NOTICE "%s: setting xattr with 
ns=%d,uid=%d,gid=%d\n", __func__,
                                unsstore[i].ns, unsstore[i].uid, 
unsstore[i].gid);
                user = ns->creator;
                lastns = ns;
-- 
1.5.4.3

_______________________________________________
Containers mailing list
[EMAIL PROTECTED]
https://lists.linux-foundation.org/mailman/listinfo/containers

_______________________________________________
Devel mailing list
[email protected]
https://openvz.org/mailman/listinfo/devel

Reply via email to