[Devel] [PATCH 09/10] userns: have ext3 use fsuserns to read userns xattrs, and add groups to userns
Serge E. Hallyn
serue at us.ibm.com
Fri Aug 22 12:47:13 PDT 2008
userns: have ext3 use fsuserns to read userns xattrs, and add groups to userns
Signed-off-by: Serge Hallyn <serue at us.ibm.com>
---
fs/ext3/super.c | 11 +++++++++--
fs/ext3/xattr.c | 19 ++++++++++++++++++-
fs/ext3/xattr.h | 3 ++-
include/linux/fs.h | 2 +-
lib/fsuserns.c | 48 +++++++++++++++++++++++++++++++++++++++++-------
5 files changed, 71 insertions(+), 12 deletions(-)
diff --git a/fs/ext3/super.c b/fs/ext3/super.c
index 3458d25..37c8404 100644
--- a/fs/ext3/super.c
+++ b/fs/ext3/super.c
@@ -723,11 +723,18 @@ static struct quotactl_ops ext3_qctl_operations = {
extern int fsuserns_add_userns(struct super_block *sb,
struct user *user, void *data);
extern int fsuserns_convert_uid_gid(struct user_namespace *ns,
- struct inode *inode, uid_t *retuid, gid_t *retgid);
+ struct inode *inode, uid_t *retuid, gid_t *retgid,
+ int (*xattrget)(struct inode *, const void *, size_t));
extern int fsuserns_is_capable(struct user_namespace *ns,
struct inode *inode, int cap);
#endif
+int ext3_convert_uid_gid(struct user_namespace *ns, struct inode *inode,
+ uid_t *retuid, gid_t *retgid)
+{
+ return fsuserns_convert_uid_gid(ns, inode, retuid, retgid, ext3_xattr_get_userns);
+}
+
static const struct super_operations ext3_sops = {
.alloc_inode = ext3_alloc_inode,
.destroy_inode = ext3_destroy_inode,
@@ -750,7 +757,7 @@ static const struct super_operations ext3_sops = {
#ifdef CONFIG_USER_NS
.add_userns = fsuserns_add_userns,
.is_capable = fsuserns_is_capable,
- .convert_uid_gid = fsuserns_convert_uid_gid,
+ .convert_uid_gid = ext3_convert_uid_gid,
#endif
};
diff --git a/fs/ext3/xattr.c b/fs/ext3/xattr.c
index da47c35..500fec7 100644
--- a/fs/ext3/xattr.c
+++ b/fs/ext3/xattr.c
@@ -331,6 +331,23 @@ ext3_xattr_get(struct inode *inode, int name_index, const char *name,
return error;
}
+int
+ext3_xattr_get_userns(struct inode *inode, void *value, size_t value_size)
+{
+ int error;
+ int name_index = EXT3_XATTR_INDEX_SECURITY;
+ char *name = "userns";
+
+ down_read(&EXT3_I(inode)->xattr_sem);
+ error = ext3_xattr_ibody_get(inode, name_index, name, value,
+ value_size);
+ if (error == -ENODATA)
+ error = ext3_xattr_block_get(inode, name_index, name, value,
+ value_size);
+ up_read(&EXT3_I(inode)->xattr_sem);
+ return error;
+}
+
static int
ext3_xattr_list_entries(struct inode *inode, struct ext3_xattr_entry *entry,
char *buffer, size_t buffer_size)
@@ -1087,7 +1104,7 @@ retry:
int error2;
error = ext3_xattr_set_handle(handle, inode, name_index, name,
- value, value_len, flags);
+ value, value_len, 0);
error2 = ext3_journal_stop(handle);
if (error == -ENOSPC &&
ext3_should_retry_alloc(inode->i_sb, &retries))
diff --git a/fs/ext3/xattr.h b/fs/ext3/xattr.h
index 8a523de..8c5b982 100644
--- a/fs/ext3/xattr.h
+++ b/fs/ext3/xattr.h
@@ -70,7 +70,8 @@ extern int ext3_xattr_get(struct inode *, int, const char *, void *, size_t);
extern int ext3_xattr_set(struct inode *, int, const char *, const void *, size_t, int);
extern int ext3_xattr_set_handle(handle_t *, struct inode *, int, const char *, const void *, size_t, int);
-extern int ext3_xattr_set_userns(struct inode *inode, const void *value, size_t value_len, int flags);
+extern int ext3_xattr_get_userns(struct inode *inode, void *value, size_t value_len);
+extern int ext3_xattr_set_userns(struct inode *inode, const void *value, size_t value_len);
extern void ext3_xattr_delete_inode(handle_t *, struct inode *);
extern void ext3_xattr_put_super(struct super_block *);
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 492abef..9ec6dac 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -1329,7 +1329,7 @@ struct super_operations {
void (*umount_begin) (struct super_block *);
int (*add_userns) (struct super_block *, struct user_struct *, void *);
int (*is_capable) (struct user_namespace *, struct inode *, int);
- uid_t (*convert_uid_gid)(struct user_namespace *, struct inode *,
+ int (*convert_uid_gid)(struct user_namespace *, struct inode *,
uid_t *, gid_t *);
int (*show_options)(struct seq_file *, struct vfsmount *);
diff --git a/lib/fsuserns.c b/lib/fsuserns.c
index db70970..ac0ca99 100644
--- a/lib/fsuserns.c
+++ b/lib/fsuserns.c
@@ -59,6 +59,12 @@ struct fsuserns_conversion_table {
LIST_HEAD(fsuserns_tables);
+struct unsstore {
+ int ns;
+ uid_t uid;
+ gid_t gid;
+};
+
struct fsuserns_conversion_table *find_table_locked(
struct super_block *sb)
{
@@ -166,11 +172,15 @@ skip:
* return 1 if we got a translation, 0 otherwise
*/
int fsuserns_convert_uid_gid(struct user_namespace *ns, struct inode *inode,
- uid_t *retuid, gid_t *retgid)
+ uid_t *retuid, gid_t *retgid,
+ int (*xattrget)(struct inode *inode, void *value, size_t value_len))
{
struct super_block *sb = inode->i_sb;
struct fsuserns_conversion_table *t;
struct fsuserns_table_entries *ep;
+ size_t valuelen;
+ struct unsstore *unsstore;
+ int i, ret;
t = find_table(sb);
if (!t)
@@ -186,6 +196,23 @@ 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, unsstore, valuelen);
+ if (ret < 0)
+ return ret;
+ for (i=0; i<3; i++)
+ if (unsstore[i].ns == ep->userns_id)
+ break;
+ if (i==3)
+ goto out;
+ *retuid = unsstore[i].uid;
+ *retgid = unsstore[i].gid;
+ return 1;
+
+out:
/* The following is BAD CODE. IT's for testing only */
if (current->uid == 0) {
if (inode->i_uid == ns->creator->uid) {
@@ -264,11 +291,6 @@ found:
}
-struct unsstore {
- int ns;
- uid_t uid;
-};
-
int fsuserns_store_creds(struct inode *inode, struct user_struct *user,
int (*xattrset)(struct inode *inode, const void *value, size_t value_len))
{
@@ -290,11 +312,23 @@ int fsuserns_store_creds(struct inode *inode, struct user_struct *user,
size = depth * sizeof(struct unsstore);
unsstore = kmalloc(size, GFP_KERNEL);
ns = user->user_ns;
+ lastns = NULL;
for (i=0; ns != &init_user_ns; i++) {
unsstore[i].ns = find_ns_id(inode, ns);
unsstore[i].uid = user->uid;
+ /*
+ * this is too bad. But putting grp on user_struct wouldn't work
+ * (think about if i do
+ * clone(CLONE_NEWUSER);
+ * change grp,
+ * clone(CLONE_NEWUSER)
+ * */
+ if (!lastns)
+ 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__,
- unsstore[i].ns, unsstore[i].uid);
+ unsstore[i].ns, unsstore[i].uid, unsstore[i].gid);
user = ns->creator;
lastns = ns;
ns = user->user_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