[Devel] [PATCH 10/10] userns: add support for readdir
Serge E. Hallyn
serue at us.ibm.com
Fri Aug 22 12:47:24 PDT 2008
Now ls works correctly inside a userns!
(but don't go doing some sort of setattr like 'chown' :)
Signed-off-by: Serge Hallyn <serue at us.ibm.com>
---
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
Containers at lists.linux-foundation.org
https://lists.linux-foundation.org/mailman/listinfo/containers
More information about the Devel
mailing list