From 6f686574cccc2ef66fb38e41f19cedd81e7b4504 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Fri, 9 Dec 2011 00:38:50 -0500 Subject: ... and the same kind of leak for mqueue Signed-off-by: Al Viro --- ipc/mqueue.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) (limited to 'ipc/mqueue.c') diff --git a/ipc/mqueue.c b/ipc/mqueue.c index 2e0ecfcc881d..5b4293d9819d 100644 --- a/ipc/mqueue.c +++ b/ipc/mqueue.c @@ -1269,7 +1269,7 @@ void mq_clear_sbinfo(struct ipc_namespace *ns) void mq_put_mnt(struct ipc_namespace *ns) { - mntput(ns->mq_mnt); + kern_unmount(ns->mq_mnt); } static int __init init_mqueue_fs(void) @@ -1291,11 +1291,9 @@ static int __init init_mqueue_fs(void) spin_lock_init(&mq_lock); - init_ipc_ns.mq_mnt = kern_mount_data(&mqueue_fs_type, &init_ipc_ns); - if (IS_ERR(init_ipc_ns.mq_mnt)) { - error = PTR_ERR(init_ipc_ns.mq_mnt); + error = mq_init_ns(&init_ipc_ns); + if (error) goto out_filesystem; - } return 0; -- cgit v1.2.3 From 6b520e0565422966cdf1c3759bd73df77b0f248c Mon Sep 17 00:00:00 2001 From: Al Viro Date: Mon, 12 Dec 2011 15:51:45 -0500 Subject: vfs: fix the stupidity with i_dentry in inode destructors Seeing that just about every destructor got that INIT_LIST_HEAD() copied into it, there is no point whatsoever keeping this INIT_LIST_HEAD in inode_init_once(); the cost of taking it into inode_init_always() will be negligible for pipes and sockets and negative for everything else. Not to mention the removal of boilerplate code from ->destroy_inode() instances... Signed-off-by: Al Viro --- ipc/mqueue.c | 1 - 1 file changed, 1 deletion(-) (limited to 'ipc/mqueue.c') diff --git a/ipc/mqueue.c b/ipc/mqueue.c index 5b4293d9819d..4e0be364aa36 100644 --- a/ipc/mqueue.c +++ b/ipc/mqueue.c @@ -243,7 +243,6 @@ static struct inode *mqueue_alloc_inode(struct super_block *sb) static void mqueue_i_callback(struct rcu_head *head) { struct inode *inode = container_of(head, struct inode, i_rcu); - INIT_LIST_HEAD(&inode->i_dentry); kmem_cache_free(mqueue_inode_cachep, MQUEUE_I(inode)); } -- cgit v1.2.3 From 4acdaf27ebe2034c342f3be57ef49aed1ad885ef Mon Sep 17 00:00:00 2001 From: Al Viro Date: Tue, 26 Jul 2011 01:42:34 -0400 Subject: switch ->create() to umode_t vfs_create() ignores everything outside of 16bit subset of its mode argument; switching it to umode_t is obviously equivalent and it's the only caller of the method Signed-off-by: Al Viro --- ipc/mqueue.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'ipc/mqueue.c') diff --git a/ipc/mqueue.c b/ipc/mqueue.c index 4e0be364aa36..57ed704d2ca7 100644 --- a/ipc/mqueue.c +++ b/ipc/mqueue.c @@ -295,7 +295,7 @@ static void mqueue_evict_inode(struct inode *inode) } static int mqueue_create(struct inode *dir, struct dentry *dentry, - int mode, struct nameidata *nd) + umode_t mode, struct nameidata *nd) { struct inode *inode; struct mq_attr *attr = dentry->d_fsdata; @@ -610,7 +610,7 @@ static int mq_attr_ok(struct ipc_namespace *ipc_ns, struct mq_attr *attr) * Invoked when creating a new queue via sys_mq_open */ static struct file *do_create(struct ipc_namespace *ipc_ns, struct dentry *dir, - struct dentry *dentry, int oflag, mode_t mode, + struct dentry *dentry, int oflag, umode_t mode, struct mq_attr *attr) { const struct cred *cred = current_cred(); -- cgit v1.2.3 From 1b9d5ff7644ddf2723c9205f4726c95ec01bf033 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Sun, 24 Jul 2011 14:18:20 -0400 Subject: mqueue: propagate umode_t Signed-off-by: Al Viro --- ipc/mqueue.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'ipc/mqueue.c') diff --git a/ipc/mqueue.c b/ipc/mqueue.c index 57ed704d2ca7..5eaecf4fc04e 100644 --- a/ipc/mqueue.c +++ b/ipc/mqueue.c @@ -108,7 +108,7 @@ static struct ipc_namespace *get_ns_from_inode(struct inode *inode) } static struct inode *mqueue_get_inode(struct super_block *sb, - struct ipc_namespace *ipc_ns, int mode, + struct ipc_namespace *ipc_ns, umode_t mode, struct mq_attr *attr) { struct user_struct *u = current_user(); -- cgit v1.2.3 From df0a42837b86567a130c44515ab620d23e7f182b Mon Sep 17 00:00:00 2001 From: Al Viro Date: Tue, 26 Jul 2011 05:26:10 -0400 Subject: switch mq_open() to umode_t --- ipc/mqueue.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'ipc/mqueue.c') diff --git a/ipc/mqueue.c b/ipc/mqueue.c index 5eaecf4fc04e..9a142a290749 100644 --- a/ipc/mqueue.c +++ b/ipc/mqueue.c @@ -679,7 +679,7 @@ err: return ERR_PTR(ret); } -SYSCALL_DEFINE4(mq_open, const char __user *, u_name, int, oflag, mode_t, mode, +SYSCALL_DEFINE4(mq_open, const char __user *, u_name, int, oflag, umode_t, mode, struct mq_attr __user *, u_attr) { struct dentry *dentry; -- cgit v1.2.3 From 6b550f9495947fc279d12c38feaf98500e8d0646 Mon Sep 17 00:00:00 2001 From: "Serge E. Hallyn" Date: Tue, 10 Jan 2012 15:11:37 -0800 Subject: user namespace: make signal.c respect user namespaces ipc/mqueue.c: for __SI_MESQ, convert the uid being sent to recipient's user namespace. (new, thanks Oleg) __send_signal: convert current's uid to the recipient's user namespace for any siginfo which is not SI_FROMKERNEL (patch from Oleg, thanks again :) do_notify_parent and do_notify_parent_cldstop: map task's uid to parent's user namespace ptrace_signal maps parent's uid into current's user namespace before including in signal to current. IIUC Oleg has argued that this shouldn't matter as the debugger will play with it, but it seems like not converting the value currently being set is misleading. Changelog: Sep 20: Inspired by Oleg's suggestion, define map_cred_ns() helper to simplify callers and help make clear what we are translating (which uid into which namespace). Passing the target task would make callers even easier to read, but we pass in user_ns because current_user_ns() != task_cred_xxx(current, user_ns). Sep 20: As recommended by Oleg, also put task_pid_vnr() under rcu_read_lock in ptrace_signal(). Sep 23: In send_signal(), detect when (user) signal is coming from an ancestor or unrelated user namespace. Pass that on to __send_signal, which sets si_uid to 0 or overflowuid if needed. Oct 12: Base on Oleg's fixup_uid() patch. On top of that, handle all SI_FROMKERNEL cases at callers, because we can't assume sender is current in those cases. Nov 10: (mhelsley) rename fixup_uid to more meaningful usern_fixup_signal_uid Nov 10: (akpm) make the !CONFIG_USER_NS case clearer Signed-off-by: Serge Hallyn Cc: Oleg Nesterov Cc: Matt Helsley Cc: "Eric W. Biederman" From: Serge Hallyn Subject: __send_signal: pass q->info, not info, to userns_fixup_signal_uid (v2) Eric Biederman pointed out that passing info is a bug and could lead to a NULL pointer deref to boot. A collection of signal, securebits, filecaps, cap_bounds, and a few other ltp tests passed with this kernel. Changelog: Nov 18: previous patch missed a leading '&' Signed-off-by: Serge Hallyn Cc: "Eric W. Biederman" From: Dan Carpenter Subject: ipc/mqueue: lock() => unlock() typo There was a double lock typo introduced in b085f4bd6b21 "user namespace: make signal.c respect user namespaces" Signed-off-by: Dan Carpenter Cc: Oleg Nesterov Cc: Matt Helsley Cc: "Eric W. Biederman" Acked-by: Serge Hallyn Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- ipc/mqueue.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'ipc/mqueue.c') diff --git a/ipc/mqueue.c b/ipc/mqueue.c index 9a142a290749..9b7c8ab7d75c 100644 --- a/ipc/mqueue.c +++ b/ipc/mqueue.c @@ -32,6 +32,7 @@ #include #include #include +#include #include #include @@ -542,9 +543,13 @@ static void __do_notify(struct mqueue_inode_info *info) sig_i.si_errno = 0; sig_i.si_code = SI_MESGQ; sig_i.si_value = info->notify.sigev_value; + /* map current pid/uid into info->owner's namespaces */ + rcu_read_lock(); sig_i.si_pid = task_tgid_nr_ns(current, ns_of_pid(info->notify_owner)); - sig_i.si_uid = current_uid(); + sig_i.si_uid = user_ns_map_uid(info->user->user_ns, + current_cred(), current_uid()); + rcu_read_unlock(); kill_pid_info(info->notify.sigev_signo, &sig_i, info->notify_owner); -- cgit v1.2.3 From 2a4e64b8f6bcbf23ddd375b78342051ae8862284 Mon Sep 17 00:00:00 2001 From: Davidlohr Bueso Date: Fri, 20 Jan 2012 14:34:01 -0800 Subject: ipc/mqueue: simplify reading msgqueue limit Because the current task is being used to get the limit, we can simply use rlimit() instead of task_rlimit(). Signed-off-by: Davidlohr Bueso Acked-by: KOSAKI Motohiro Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- ipc/mqueue.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'ipc/mqueue.c') diff --git a/ipc/mqueue.c b/ipc/mqueue.c index 9b7c8ab7d75c..86ee272de210 100644 --- a/ipc/mqueue.c +++ b/ipc/mqueue.c @@ -128,7 +128,6 @@ static struct inode *mqueue_get_inode(struct super_block *sb, if (S_ISREG(mode)) { struct mqueue_inode_info *info; - struct task_struct *p = current; unsigned long mq_bytes, mq_msg_tblsz; inode->i_fop = &mqueue_file_operations; @@ -159,7 +158,7 @@ static struct inode *mqueue_get_inode(struct super_block *sb, spin_lock(&mq_lock); if (u->mq_bytes + mq_bytes < u->mq_bytes || - u->mq_bytes + mq_bytes > task_rlimit(p, RLIMIT_MSGQUEUE)) { + u->mq_bytes + mq_bytes > rlimit(RLIMIT_MSGQUEUE)) { spin_unlock(&mq_lock); /* mqueue_evict_inode() releases info->messages */ ret = -EMFILE; -- cgit v1.2.3