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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.