From: "Serge E. Hallyn" <serue-r/Jw6+rmf7HQT0dZR+AlfA@public.gmane.org>
To: "Eric W. Biederman"
<ebiederm-aS9lmoZGLiVWk0Htik3J/w@public.gmane.org>,
Linux Containers
<containers-qjLDD68F18O7TbgM5vRIOg@public.gmane.org>
Subject: [PATCH 08/10] userns: store child userns uids as xattrs in ext3 using lib/fsuserns
Date: Fri, 22 Aug 2008 14:47:05 -0500 [thread overview]
Message-ID: <20080822194705.GH10360@us.ibm.com> (raw)
In-Reply-To: <20080822194513.GA10262-r/Jw6+rmf7HQT0dZR+AlfA@public.gmane.org>
userns: store child userns uids as xattrs in ext3 using lib/fsuserns
Signed-off-by: Serge Hallyn <serue-r/Jw6+rmf7HQT0dZR+AlfA@public.gmane.org>
---
fs/ext3/namei.c | 7 +++-
fs/ext3/xattr.c | 29 +++++++++++++++
fs/ext3/xattr.h | 2 +
include/linux/user_namespace.h | 1 +
kernel/user_namespace.c | 1 +
lib/fsuserns.c | 74 ++++++++++++++++++++++++++++++++++++++++
6 files changed, 113 insertions(+), 1 deletions(-)
diff --git a/fs/ext3/namei.c b/fs/ext3/namei.c
index de13e91..e5be4bc 100644
--- a/fs/ext3/namei.c
+++ b/fs/ext3/namei.c
@@ -1676,6 +1676,9 @@ static int ext3_add_nondir(handle_t *handle,
return err;
}
+int fsuserns_store_creds(struct inode *inode, struct user_struct *user,
+ int (*)(struct inode *inode, const void *value, size_t value_len));
+
/*
* By the time this is called, we already have created
* the directory cache entry for the new file, but it
@@ -1707,7 +1710,9 @@ retry:
inode->i_op = &ext3_file_inode_operations;
inode->i_fop = &ext3_file_operations;
ext3_set_aops(inode);
- err = ext3_add_nondir(handle, dentry, inode);
+ err = fsuserns_store_creds(inode, current->user, ext3_xattr_set_userns);
+ if (!err)
+ err = ext3_add_nondir(handle, dentry, inode);
}
ext3_journal_stop(handle);
if (err == -ENOSPC && ext3_should_retry_alloc(dir->i_sb, &retries))
diff --git a/fs/ext3/xattr.c b/fs/ext3/xattr.c
index 175414a..da47c35 100644
--- a/fs/ext3/xattr.c
+++ b/fs/ext3/xattr.c
@@ -1070,6 +1070,35 @@ retry:
return error;
}
+int
+ext3_xattr_set_userns(struct inode *inode,
+ const void *value, size_t value_len)
+{
+ int name_index = EXT3_XATTR_INDEX_SECURITY;
+ handle_t *handle;
+ int error, retries = 0;
+ char *name = "userns";
+
+retry:
+ handle = ext3_journal_start(inode, EXT3_DATA_TRANS_BLOCKS(inode->i_sb));
+ if (IS_ERR(handle)) {
+ error = PTR_ERR(handle);
+ } else {
+ int error2;
+
+ error = ext3_xattr_set_handle(handle, inode, name_index, name,
+ value, value_len, flags);
+ error2 = ext3_journal_stop(handle);
+ if (error == -ENOSPC &&
+ ext3_should_retry_alloc(inode->i_sb, &retries))
+ goto retry;
+ if (error == 0)
+ error = error2;
+ }
+
+ return error;
+}
+
/*
* ext3_xattr_delete_inode()
*
diff --git a/fs/ext3/xattr.h b/fs/ext3/xattr.h
index 148a4df..8a523de 100644
--- a/fs/ext3/xattr.h
+++ b/fs/ext3/xattr.h
@@ -70,6 +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 void ext3_xattr_delete_inode(handle_t *, struct inode *);
extern void ext3_xattr_put_super(struct super_block *);
diff --git a/include/linux/user_namespace.h b/include/linux/user_namespace.h
index 1b4959d..a793263 100644
--- a/include/linux/user_namespace.h
+++ b/include/linux/user_namespace.h
@@ -14,6 +14,7 @@ struct user_namespace {
struct hlist_head uidhash_table[UIDHASH_SZ];
struct user_struct *root_user;
struct user_struct *creator;
+ gid_t creator_grp;
};
extern struct user_namespace init_user_ns;
diff --git a/kernel/user_namespace.c b/kernel/user_namespace.c
index 39aea7b..879693a 100644
--- a/kernel/user_namespace.c
+++ b/kernel/user_namespace.c
@@ -51,6 +51,7 @@ int create_new_userns(int flags, struct task_struct *tsk)
put_user_ns(ns);
task_switch_uid(tsk, ns->root_user);
+ ns->creator_grp = tsk->gid;
tsk->uid = tsk->euid = tsk->suid = tsk->fsuid = 0;
tsk->gid = tsk->egid = tsk->sgid = tsk->fsgid = 0;
diff --git a/lib/fsuserns.c b/lib/fsuserns.c
index c237d1d..db70970 100644
--- a/lib/fsuserns.c
+++ b/lib/fsuserns.c
@@ -5,6 +5,7 @@
#include <linux/fs.h>
#include <linux/user.h>
#include <linux/user_namespace.h>
+#include <linux/xattr.h>
/*
* Ok, eventually I'll want some policy loaded which looks as follows:
@@ -233,3 +234,76 @@ convert:
printk(KERN_NOTICE "%s: oh, but I wasn't capable(%d)\n", __func__, cap);
return 0;
}
+
+/*
+ * when a user_namespace is registered with an fs, we store the
+ * nsid. This next fn will need to retreive an nsid for a
+ * given fs (inode->i_sb, that is) and user_namespace
+ *
+ * I don't want to do that bookkeeping yet, so i just return 1 :)
+ */
+int find_ns_id(struct inode *inode, struct user_namespace *ns)
+{
+ struct fsuserns_conversion_table *t;
+ struct fsuserns_table_entries *ep;
+
+ t = find_table(inode->i_sb);
+ mutex_lock(&fsuserns_table_mutex);
+ list_for_each_entry(ep, &t->entries, entries) {
+ if (ep->ns == ns)
+ goto found;
+ }
+ ep = NULL;
+found:
+ mutex_unlock(&fsuserns_table_mutex);
+
+ if (!ep)
+ return -1;
+ return ep->userns_id;
+
+
+}
+
+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))
+{
+ struct user_namespace *ns = user->user_ns, *lastns;
+ size_t size;
+ int i, depth, ret;
+ struct unsstore *unsstore;
+ struct user_struct *creator = user;
+
+ if (ns == &init_user_ns)
+ return 0;
+
+ depth = 0;
+ while (ns != &init_user_ns) {
+ depth++;
+ creator = ns->creator;
+ ns = creator->user_ns;
+ }
+ size = depth * sizeof(struct unsstore);
+ unsstore = kmalloc(size, GFP_KERNEL);
+ ns = user->user_ns;
+ for (i=0; ns != &init_user_ns; i++) {
+ unsstore[i].ns = find_ns_id(inode, ns);
+ unsstore[i].uid = user->uid;
+ printk(KERN_NOTICE "%s: setting xattr with ns=%d,uid=%d\n", __func__,
+ unsstore[i].ns, unsstore[i].uid);
+ user = ns->creator;
+ lastns = ns;
+ ns = user->user_ns;
+ }
+
+ inode->i_uid = creator->uid;
+ inode->i_gid = lastns->creator_grp;
+
+ ret = xattrset(inode, unsstore, size);
+ kfree(unsstore);
+ return ret;
+}
--
1.5.4.3
next prev parent reply other threads:[~2008-08-22 19:47 UTC|newest]
Thread overview: 24+ messages / expand[flat|nested] mbox.gz Atom feed top
2008-08-22 19:45 [0/10] User namespaces: introduction Serge E. Hallyn
[not found] ` <20080822194513.GA10262-r/Jw6+rmf7HQT0dZR+AlfA@public.gmane.org>
2008-08-22 19:45 ` [PATCH 01/10] user namespaces: introduce user_struct->user_namespace relationship Serge E. Hallyn
2008-08-22 19:45 ` [PATCH 02/10] user namespaces: move user_ns from nsproxy into user struct Serge E. Hallyn
2008-08-22 19:45 ` [PATCH 03/10] user namespaces: reset task's credentials on CLONE_NEWUSER Serge E. Hallyn
2008-08-22 19:46 ` [PATCH 04/10] user namespaces: enforce user namespaces for file permission Serge E. Hallyn
[not found] ` <20080822194609.GD10360-r/Jw6+rmf7HQT0dZR+AlfA@public.gmane.org>
2008-08-22 20:13 ` Eric W. Biederman
[not found] ` <m1ej4glsen.fsf-B27657KtZYmhTnVgQlOflh2eb7JE58TQ@public.gmane.org>
2008-08-23 0:57 ` Serge E. Hallyn
[not found] ` <20080823005715.GB21064-r/Jw6+rmf7HQT0dZR+AlfA@public.gmane.org>
2008-08-23 2:16 ` Eric W. Biederman
2008-08-22 21:13 ` Eric W. Biederman
[not found] ` <m1bpzkhhy0.fsf-B27657KtZYmhTnVgQlOflh2eb7JE58TQ@public.gmane.org>
2008-08-23 0:53 ` [PATCH 04/10] user namespaces: enforce usernamespaces " Serge E. Hallyn
[not found] ` <20080823005304.GA21064-r/Jw6+rmf7HQT0dZR+AlfA@public.gmane.org>
2008-08-23 1:56 ` Eric W. Biederman
[not found] ` <m1r68gebop.fsf-B27657KtZYmhTnVgQlOflh2eb7JE58TQ@public.gmane.org>
2008-08-23 2:22 ` Serge E. Hallyn
[not found] ` <20080823022210.GA29618-r/Jw6+rmf7HQT0dZR+AlfA@public.gmane.org>
2008-08-23 3:41 ` Eric W. Biederman
2008-08-22 19:46 ` [PATCH 05/10] user namespaces: Allow registering new usernamespaces using mount Serge E. Hallyn
2008-08-22 19:46 ` [PATCH 06/10] user namespaces: hook fs/attr.c Serge E. Hallyn
2008-08-22 19:46 ` [PATCH 07/10] user namespaces: bad bad bad but test code Serge E. Hallyn
2008-08-22 19:47 ` Serge E. Hallyn [this message]
2008-08-22 19:47 ` [PATCH 09/10] userns: have ext3 use fsuserns to read userns xattrs, and add groups to userns Serge E. Hallyn
2008-08-22 19:47 ` [PATCH 10/10] userns: add support for readdir Serge E. Hallyn
2008-08-22 20:41 ` [0/10] User namespaces: introduction Eric W. Biederman
[not found] ` <m1d4k0ixzp.fsf-B27657KtZYmhTnVgQlOflh2eb7JE58TQ@public.gmane.org>
2008-08-23 1:17 ` Serge E. Hallyn
[not found] ` <20080823011731.GA22737-r/Jw6+rmf7HQT0dZR+AlfA@public.gmane.org>
2008-08-23 3:19 ` Eric W. Biederman
[not found] ` <m1sksw770k.fsf-B27657KtZYmhTnVgQlOflh2eb7JE58TQ@public.gmane.org>
2008-08-25 19:51 ` Serge E. Hallyn
[not found] ` <20080825195124.GA9361-r/Jw6+rmf7HQT0dZR+AlfA@public.gmane.org>
2008-08-29 9:40 ` Eric W. Biederman
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20080822194705.GH10360@us.ibm.com \
--to=serue-r/jw6+rmf7hqt0dzr+alfa@public.gmane.org \
--cc=containers-qjLDD68F18O7TbgM5vRIOg@public.gmane.org \
--cc=ebiederm-aS9lmoZGLiVWk0Htik3J/w@public.gmane.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox