aboutsummaryrefslogtreecommitdiffstats
path: root/ipc
diff options
context:
space:
mode:
Diffstat (limited to 'ipc')
-rw-r--r--ipc/Makefile1
-rw-r--r--ipc/ipc_sysctl.c95
-rw-r--r--ipc/mq_sysctl.c115
-rw-r--r--ipc/mqueue.c264
-rw-r--r--ipc/msgutil.c19
-rw-r--r--ipc/namespace.c56
-rw-r--r--ipc/sem.c4
-rw-r--r--ipc/shm.c28
-rw-r--r--ipc/util.c11
-rw-r--r--ipc/util.h24
10 files changed, 359 insertions, 258 deletions
diff --git a/ipc/Makefile b/ipc/Makefile
index 65c384395801..4e1955ea815d 100644
--- a/ipc/Makefile
+++ b/ipc/Makefile
@@ -8,4 +8,5 @@ obj-$(CONFIG_SYSVIPC_SYSCTL) += ipc_sysctl.o
8obj_mq-$(CONFIG_COMPAT) += compat_mq.o 8obj_mq-$(CONFIG_COMPAT) += compat_mq.o
9obj-$(CONFIG_POSIX_MQUEUE) += mqueue.o msgutil.o $(obj_mq-y) 9obj-$(CONFIG_POSIX_MQUEUE) += mqueue.o msgutil.o $(obj_mq-y)
10obj-$(CONFIG_IPC_NS) += namespace.o 10obj-$(CONFIG_IPC_NS) += namespace.o
11obj-$(CONFIG_POSIX_MQUEUE_SYSCTL) += mq_sysctl.o
11 12
diff --git a/ipc/ipc_sysctl.c b/ipc/ipc_sysctl.c
index 4a7a12c95abe..56410faa4550 100644
--- a/ipc/ipc_sysctl.c
+++ b/ipc/ipc_sysctl.c
@@ -26,19 +26,19 @@ static void *get_ipc(ctl_table *table)
26 return which; 26 return which;
27} 27}
28 28
29#ifdef CONFIG_PROC_FS 29#ifdef CONFIG_PROC_SYSCTL
30static int proc_ipc_dointvec(ctl_table *table, int write, struct file *filp, 30static int proc_ipc_dointvec(ctl_table *table, int write,
31 void __user *buffer, size_t *lenp, loff_t *ppos) 31 void __user *buffer, size_t *lenp, loff_t *ppos)
32{ 32{
33 struct ctl_table ipc_table; 33 struct ctl_table ipc_table;
34 memcpy(&ipc_table, table, sizeof(ipc_table)); 34 memcpy(&ipc_table, table, sizeof(ipc_table));
35 ipc_table.data = get_ipc(table); 35 ipc_table.data = get_ipc(table);
36 36
37 return proc_dointvec(&ipc_table, write, filp, buffer, lenp, ppos); 37 return proc_dointvec(&ipc_table, write, buffer, lenp, ppos);
38} 38}
39 39
40static int proc_ipc_callback_dointvec(ctl_table *table, int write, 40static int proc_ipc_callback_dointvec(ctl_table *table, int write,
41 struct file *filp, void __user *buffer, size_t *lenp, loff_t *ppos) 41 void __user *buffer, size_t *lenp, loff_t *ppos)
42{ 42{
43 struct ctl_table ipc_table; 43 struct ctl_table ipc_table;
44 size_t lenp_bef = *lenp; 44 size_t lenp_bef = *lenp;
@@ -47,7 +47,7 @@ static int proc_ipc_callback_dointvec(ctl_table *table, int write,
47 memcpy(&ipc_table, table, sizeof(ipc_table)); 47 memcpy(&ipc_table, table, sizeof(ipc_table));
48 ipc_table.data = get_ipc(table); 48 ipc_table.data = get_ipc(table);
49 49
50 rc = proc_dointvec(&ipc_table, write, filp, buffer, lenp, ppos); 50 rc = proc_dointvec(&ipc_table, write, buffer, lenp, ppos);
51 51
52 if (write && !rc && lenp_bef == *lenp) 52 if (write && !rc && lenp_bef == *lenp)
53 /* 53 /*
@@ -61,13 +61,13 @@ static int proc_ipc_callback_dointvec(ctl_table *table, int write,
61} 61}
62 62
63static int proc_ipc_doulongvec_minmax(ctl_table *table, int write, 63static int proc_ipc_doulongvec_minmax(ctl_table *table, int write,
64 struct file *filp, void __user *buffer, size_t *lenp, loff_t *ppos) 64 void __user *buffer, size_t *lenp, loff_t *ppos)
65{ 65{
66 struct ctl_table ipc_table; 66 struct ctl_table ipc_table;
67 memcpy(&ipc_table, table, sizeof(ipc_table)); 67 memcpy(&ipc_table, table, sizeof(ipc_table));
68 ipc_table.data = get_ipc(table); 68 ipc_table.data = get_ipc(table);
69 69
70 return proc_doulongvec_minmax(&ipc_table, write, filp, buffer, 70 return proc_doulongvec_minmax(&ipc_table, write, buffer,
71 lenp, ppos); 71 lenp, ppos);
72} 72}
73 73
@@ -95,7 +95,7 @@ static void ipc_auto_callback(int val)
95} 95}
96 96
97static int proc_ipcauto_dointvec_minmax(ctl_table *table, int write, 97static int proc_ipcauto_dointvec_minmax(ctl_table *table, int write,
98 struct file *filp, void __user *buffer, size_t *lenp, loff_t *ppos) 98 void __user *buffer, size_t *lenp, loff_t *ppos)
99{ 99{
100 struct ctl_table ipc_table; 100 struct ctl_table ipc_table;
101 size_t lenp_bef = *lenp; 101 size_t lenp_bef = *lenp;
@@ -106,7 +106,7 @@ static int proc_ipcauto_dointvec_minmax(ctl_table *table, int write,
106 ipc_table.data = get_ipc(table); 106 ipc_table.data = get_ipc(table);
107 oldval = *((int *)(ipc_table.data)); 107 oldval = *((int *)(ipc_table.data));
108 108
109 rc = proc_dointvec_minmax(&ipc_table, write, filp, buffer, lenp, ppos); 109 rc = proc_dointvec_minmax(&ipc_table, write, buffer, lenp, ppos);
110 110
111 if (write && !rc && lenp_bef == *lenp) { 111 if (write && !rc && lenp_bef == *lenp) {
112 int newval = *((int *)(ipc_table.data)); 112 int newval = *((int *)(ipc_table.data));
@@ -129,136 +129,60 @@ static int proc_ipcauto_dointvec_minmax(ctl_table *table, int write,
129#define proc_ipcauto_dointvec_minmax NULL 129#define proc_ipcauto_dointvec_minmax NULL
130#endif 130#endif
131 131
132#ifdef CONFIG_SYSCTL_SYSCALL
133/* The generic sysctl ipc data routine. */
134static int sysctl_ipc_data(ctl_table *table,
135 void __user *oldval, size_t __user *oldlenp,
136 void __user *newval, size_t newlen)
137{
138 size_t len;
139 void *data;
140
141 /* Get out of I don't have a variable */
142 if (!table->data || !table->maxlen)
143 return -ENOTDIR;
144
145 data = get_ipc(table);
146 if (!data)
147 return -ENOTDIR;
148
149 if (oldval && oldlenp) {
150 if (get_user(len, oldlenp))
151 return -EFAULT;
152 if (len) {
153 if (len > table->maxlen)
154 len = table->maxlen;
155 if (copy_to_user(oldval, data, len))
156 return -EFAULT;
157 if (put_user(len, oldlenp))
158 return -EFAULT;
159 }
160 }
161
162 if (newval && newlen) {
163 if (newlen > table->maxlen)
164 newlen = table->maxlen;
165
166 if (copy_from_user(data, newval, newlen))
167 return -EFAULT;
168 }
169 return 1;
170}
171
172static int sysctl_ipc_registered_data(ctl_table *table,
173 void __user *oldval, size_t __user *oldlenp,
174 void __user *newval, size_t newlen)
175{
176 int rc;
177
178 rc = sysctl_ipc_data(table, oldval, oldlenp, newval, newlen);
179
180 if (newval && newlen && rc > 0)
181 /*
182 * Tunable has successfully been changed from userland
183 */
184 unregister_ipcns_notifier(current->nsproxy->ipc_ns);
185
186 return rc;
187}
188#else
189#define sysctl_ipc_data NULL
190#define sysctl_ipc_registered_data NULL
191#endif
192
193static int zero; 132static int zero;
194static int one = 1; 133static int one = 1;
195 134
196static struct ctl_table ipc_kern_table[] = { 135static struct ctl_table ipc_kern_table[] = {
197 { 136 {
198 .ctl_name = KERN_SHMMAX,
199 .procname = "shmmax", 137 .procname = "shmmax",
200 .data = &init_ipc_ns.shm_ctlmax, 138 .data = &init_ipc_ns.shm_ctlmax,
201 .maxlen = sizeof (init_ipc_ns.shm_ctlmax), 139 .maxlen = sizeof (init_ipc_ns.shm_ctlmax),
202 .mode = 0644, 140 .mode = 0644,
203 .proc_handler = proc_ipc_doulongvec_minmax, 141 .proc_handler = proc_ipc_doulongvec_minmax,
204 .strategy = sysctl_ipc_data,
205 }, 142 },
206 { 143 {
207 .ctl_name = KERN_SHMALL,
208 .procname = "shmall", 144 .procname = "shmall",
209 .data = &init_ipc_ns.shm_ctlall, 145 .data = &init_ipc_ns.shm_ctlall,
210 .maxlen = sizeof (init_ipc_ns.shm_ctlall), 146 .maxlen = sizeof (init_ipc_ns.shm_ctlall),
211 .mode = 0644, 147 .mode = 0644,
212 .proc_handler = proc_ipc_doulongvec_minmax, 148 .proc_handler = proc_ipc_doulongvec_minmax,
213 .strategy = sysctl_ipc_data,
214 }, 149 },
215 { 150 {
216 .ctl_name = KERN_SHMMNI,
217 .procname = "shmmni", 151 .procname = "shmmni",
218 .data = &init_ipc_ns.shm_ctlmni, 152 .data = &init_ipc_ns.shm_ctlmni,
219 .maxlen = sizeof (init_ipc_ns.shm_ctlmni), 153 .maxlen = sizeof (init_ipc_ns.shm_ctlmni),
220 .mode = 0644, 154 .mode = 0644,
221 .proc_handler = proc_ipc_dointvec, 155 .proc_handler = proc_ipc_dointvec,
222 .strategy = sysctl_ipc_data,
223 }, 156 },
224 { 157 {
225 .ctl_name = KERN_MSGMAX,
226 .procname = "msgmax", 158 .procname = "msgmax",
227 .data = &init_ipc_ns.msg_ctlmax, 159 .data = &init_ipc_ns.msg_ctlmax,
228 .maxlen = sizeof (init_ipc_ns.msg_ctlmax), 160 .maxlen = sizeof (init_ipc_ns.msg_ctlmax),
229 .mode = 0644, 161 .mode = 0644,
230 .proc_handler = proc_ipc_dointvec, 162 .proc_handler = proc_ipc_dointvec,
231 .strategy = sysctl_ipc_data,
232 }, 163 },
233 { 164 {
234 .ctl_name = KERN_MSGMNI,
235 .procname = "msgmni", 165 .procname = "msgmni",
236 .data = &init_ipc_ns.msg_ctlmni, 166 .data = &init_ipc_ns.msg_ctlmni,
237 .maxlen = sizeof (init_ipc_ns.msg_ctlmni), 167 .maxlen = sizeof (init_ipc_ns.msg_ctlmni),
238 .mode = 0644, 168 .mode = 0644,
239 .proc_handler = proc_ipc_callback_dointvec, 169 .proc_handler = proc_ipc_callback_dointvec,
240 .strategy = sysctl_ipc_registered_data,
241 }, 170 },
242 { 171 {
243 .ctl_name = KERN_MSGMNB,
244 .procname = "msgmnb", 172 .procname = "msgmnb",
245 .data = &init_ipc_ns.msg_ctlmnb, 173 .data = &init_ipc_ns.msg_ctlmnb,
246 .maxlen = sizeof (init_ipc_ns.msg_ctlmnb), 174 .maxlen = sizeof (init_ipc_ns.msg_ctlmnb),
247 .mode = 0644, 175 .mode = 0644,
248 .proc_handler = proc_ipc_dointvec, 176 .proc_handler = proc_ipc_dointvec,
249 .strategy = sysctl_ipc_data,
250 }, 177 },
251 { 178 {
252 .ctl_name = KERN_SEM,
253 .procname = "sem", 179 .procname = "sem",
254 .data = &init_ipc_ns.sem_ctls, 180 .data = &init_ipc_ns.sem_ctls,
255 .maxlen = 4*sizeof (int), 181 .maxlen = 4*sizeof (int),
256 .mode = 0644, 182 .mode = 0644,
257 .proc_handler = proc_ipc_dointvec, 183 .proc_handler = proc_ipc_dointvec,
258 .strategy = sysctl_ipc_data,
259 }, 184 },
260 { 185 {
261 .ctl_name = CTL_UNNUMBERED,
262 .procname = "auto_msgmni", 186 .procname = "auto_msgmni",
263 .data = &init_ipc_ns.auto_msgmni, 187 .data = &init_ipc_ns.auto_msgmni,
264 .maxlen = sizeof(int), 188 .maxlen = sizeof(int),
@@ -272,7 +196,6 @@ static struct ctl_table ipc_kern_table[] = {
272 196
273static struct ctl_table ipc_root_table[] = { 197static struct ctl_table ipc_root_table[] = {
274 { 198 {
275 .ctl_name = CTL_KERN,
276 .procname = "kernel", 199 .procname = "kernel",
277 .mode = 0555, 200 .mode = 0555,
278 .child = ipc_kern_table, 201 .child = ipc_kern_table,
diff --git a/ipc/mq_sysctl.c b/ipc/mq_sysctl.c
new file mode 100644
index 000000000000..0c09366b96f3
--- /dev/null
+++ b/ipc/mq_sysctl.c
@@ -0,0 +1,115 @@
1/*
2 * Copyright (C) 2007 IBM Corporation
3 *
4 * Author: Cedric Le Goater <clg@fr.ibm.com>
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation, version 2 of the
9 * License.
10 */
11
12#include <linux/nsproxy.h>
13#include <linux/ipc_namespace.h>
14#include <linux/sysctl.h>
15
16/*
17 * Define the ranges various user-specified maximum values can
18 * be set to.
19 */
20#define MIN_MSGMAX 1 /* min value for msg_max */
21#define MAX_MSGMAX HARD_MSGMAX /* max value for msg_max */
22#define MIN_MSGSIZEMAX 128 /* min value for msgsize_max */
23#define MAX_MSGSIZEMAX (8192*128) /* max value for msgsize_max */
24
25#ifdef CONFIG_PROC_SYSCTL
26static void *get_mq(ctl_table *table)
27{
28 char *which = table->data;
29 struct ipc_namespace *ipc_ns = current->nsproxy->ipc_ns;
30 which = (which - (char *)&init_ipc_ns) + (char *)ipc_ns;
31 return which;
32}
33
34static int proc_mq_dointvec(ctl_table *table, int write,
35 void __user *buffer, size_t *lenp, loff_t *ppos)
36{
37 struct ctl_table mq_table;
38 memcpy(&mq_table, table, sizeof(mq_table));
39 mq_table.data = get_mq(table);
40
41 return proc_dointvec(&mq_table, write, buffer, lenp, ppos);
42}
43
44static int proc_mq_dointvec_minmax(ctl_table *table, int write,
45 void __user *buffer, size_t *lenp, loff_t *ppos)
46{
47 struct ctl_table mq_table;
48 memcpy(&mq_table, table, sizeof(mq_table));
49 mq_table.data = get_mq(table);
50
51 return proc_dointvec_minmax(&mq_table, write, buffer,
52 lenp, ppos);
53}
54#else
55#define proc_mq_dointvec NULL
56#define proc_mq_dointvec_minmax NULL
57#endif
58
59static int msg_max_limit_min = MIN_MSGMAX;
60static int msg_max_limit_max = MAX_MSGMAX;
61
62static int msg_maxsize_limit_min = MIN_MSGSIZEMAX;
63static int msg_maxsize_limit_max = MAX_MSGSIZEMAX;
64
65static ctl_table mq_sysctls[] = {
66 {
67 .procname = "queues_max",
68 .data = &init_ipc_ns.mq_queues_max,
69 .maxlen = sizeof(int),
70 .mode = 0644,
71 .proc_handler = proc_mq_dointvec,
72 },
73 {
74 .procname = "msg_max",
75 .data = &init_ipc_ns.mq_msg_max,
76 .maxlen = sizeof(int),
77 .mode = 0644,
78 .proc_handler = proc_mq_dointvec_minmax,
79 .extra1 = &msg_max_limit_min,
80 .extra2 = &msg_max_limit_max,
81 },
82 {
83 .procname = "msgsize_max",
84 .data = &init_ipc_ns.mq_msgsize_max,
85 .maxlen = sizeof(int),
86 .mode = 0644,
87 .proc_handler = proc_mq_dointvec_minmax,
88 .extra1 = &msg_maxsize_limit_min,
89 .extra2 = &msg_maxsize_limit_max,
90 },
91 {}
92};
93
94static ctl_table mq_sysctl_dir[] = {
95 {
96 .procname = "mqueue",
97 .mode = 0555,
98 .child = mq_sysctls,
99 },
100 {}
101};
102
103static ctl_table mq_sysctl_root[] = {
104 {
105 .procname = "fs",
106 .mode = 0555,
107 .child = mq_sysctl_dir,
108 },
109 {}
110};
111
112struct ctl_table_header *mq_register_sysctl_table(void)
113{
114 return register_sysctl_table(mq_sysctl_root);
115}
diff --git a/ipc/mqueue.c b/ipc/mqueue.c
index a8ddadbc7459..ee9d69707c0a 100644
--- a/ipc/mqueue.c
+++ b/ipc/mqueue.c
@@ -31,6 +31,8 @@
31#include <linux/mutex.h> 31#include <linux/mutex.h>
32#include <linux/nsproxy.h> 32#include <linux/nsproxy.h>
33#include <linux/pid.h> 33#include <linux/pid.h>
34#include <linux/ipc_namespace.h>
35#include <linux/ima.h>
34 36
35#include <net/sock.h> 37#include <net/sock.h>
36#include "util.h" 38#include "util.h"
@@ -46,21 +48,6 @@
46#define STATE_PENDING 1 48#define STATE_PENDING 1
47#define STATE_READY 2 49#define STATE_READY 2
48 50
49/* default values */
50#define DFLT_QUEUESMAX 256 /* max number of message queues */
51#define DFLT_MSGMAX 10 /* max number of messages in each queue */
52#define HARD_MSGMAX (131072/sizeof(void*))
53#define DFLT_MSGSIZEMAX 8192 /* max message size */
54
55/*
56 * Define the ranges various user-specified maximum values can
57 * be set to.
58 */
59#define MIN_MSGMAX 1 /* min value for msg_max */
60#define MAX_MSGMAX HARD_MSGMAX /* max value for msg_max */
61#define MIN_MSGSIZEMAX 128 /* min value for msgsize_max */
62#define MAX_MSGSIZEMAX (8192*128) /* max value for msgsize_max */
63
64struct ext_wait_queue { /* queue of sleeping tasks */ 51struct ext_wait_queue { /* queue of sleeping tasks */
65 struct task_struct *task; 52 struct task_struct *task;
66 struct list_head list; 53 struct list_head list;
@@ -90,17 +77,10 @@ struct mqueue_inode_info {
90 77
91static const struct inode_operations mqueue_dir_inode_operations; 78static const struct inode_operations mqueue_dir_inode_operations;
92static const struct file_operations mqueue_file_operations; 79static const struct file_operations mqueue_file_operations;
93static struct super_operations mqueue_super_ops; 80static const struct super_operations mqueue_super_ops;
94static void remove_notification(struct mqueue_inode_info *info); 81static void remove_notification(struct mqueue_inode_info *info);
95 82
96static spinlock_t mq_lock;
97static struct kmem_cache *mqueue_inode_cachep; 83static struct kmem_cache *mqueue_inode_cachep;
98static struct vfsmount *mqueue_mnt;
99
100static unsigned int queues_count;
101static unsigned int queues_max = DFLT_QUEUESMAX;
102static unsigned int msg_max = DFLT_MSGMAX;
103static unsigned int msgsize_max = DFLT_MSGSIZEMAX;
104 84
105static struct ctl_table_header * mq_sysctl_table; 85static struct ctl_table_header * mq_sysctl_table;
106 86
@@ -109,8 +89,27 @@ static inline struct mqueue_inode_info *MQUEUE_I(struct inode *inode)
109 return container_of(inode, struct mqueue_inode_info, vfs_inode); 89 return container_of(inode, struct mqueue_inode_info, vfs_inode);
110} 90}
111 91
112static struct inode *mqueue_get_inode(struct super_block *sb, int mode, 92/*
113 struct mq_attr *attr) 93 * This routine should be called with the mq_lock held.
94 */
95static inline struct ipc_namespace *__get_ns_from_inode(struct inode *inode)
96{
97 return get_ipc_ns(inode->i_sb->s_fs_info);
98}
99
100static struct ipc_namespace *get_ns_from_inode(struct inode *inode)
101{
102 struct ipc_namespace *ns;
103
104 spin_lock(&mq_lock);
105 ns = __get_ns_from_inode(inode);
106 spin_unlock(&mq_lock);
107 return ns;
108}
109
110static struct inode *mqueue_get_inode(struct super_block *sb,
111 struct ipc_namespace *ipc_ns, int mode,
112 struct mq_attr *attr)
114{ 113{
115 struct user_struct *u = current_user(); 114 struct user_struct *u = current_user();
116 struct inode *inode; 115 struct inode *inode;
@@ -141,8 +140,8 @@ static struct inode *mqueue_get_inode(struct super_block *sb, int mode,
141 info->qsize = 0; 140 info->qsize = 0;
142 info->user = NULL; /* set when all is ok */ 141 info->user = NULL; /* set when all is ok */
143 memset(&info->attr, 0, sizeof(info->attr)); 142 memset(&info->attr, 0, sizeof(info->attr));
144 info->attr.mq_maxmsg = msg_max; 143 info->attr.mq_maxmsg = ipc_ns->mq_msg_max;
145 info->attr.mq_msgsize = msgsize_max; 144 info->attr.mq_msgsize = ipc_ns->mq_msgsize_max;
146 if (attr) { 145 if (attr) {
147 info->attr.mq_maxmsg = attr->mq_maxmsg; 146 info->attr.mq_maxmsg = attr->mq_maxmsg;
148 info->attr.mq_msgsize = attr->mq_msgsize; 147 info->attr.mq_msgsize = attr->mq_msgsize;
@@ -188,30 +187,38 @@ out_inode:
188static int mqueue_fill_super(struct super_block *sb, void *data, int silent) 187static int mqueue_fill_super(struct super_block *sb, void *data, int silent)
189{ 188{
190 struct inode *inode; 189 struct inode *inode;
190 struct ipc_namespace *ns = data;
191 int error = 0;
191 192
192 sb->s_blocksize = PAGE_CACHE_SIZE; 193 sb->s_blocksize = PAGE_CACHE_SIZE;
193 sb->s_blocksize_bits = PAGE_CACHE_SHIFT; 194 sb->s_blocksize_bits = PAGE_CACHE_SHIFT;
194 sb->s_magic = MQUEUE_MAGIC; 195 sb->s_magic = MQUEUE_MAGIC;
195 sb->s_op = &mqueue_super_ops; 196 sb->s_op = &mqueue_super_ops;
196 197
197 inode = mqueue_get_inode(sb, S_IFDIR | S_ISVTX | S_IRWXUGO, NULL); 198 inode = mqueue_get_inode(sb, ns, S_IFDIR | S_ISVTX | S_IRWXUGO,
198 if (!inode) 199 NULL);
199 return -ENOMEM; 200 if (!inode) {
201 error = -ENOMEM;
202 goto out;
203 }
200 204
201 sb->s_root = d_alloc_root(inode); 205 sb->s_root = d_alloc_root(inode);
202 if (!sb->s_root) { 206 if (!sb->s_root) {
203 iput(inode); 207 iput(inode);
204 return -ENOMEM; 208 error = -ENOMEM;
205 } 209 }
206 210
207 return 0; 211out:
212 return error;
208} 213}
209 214
210static int mqueue_get_sb(struct file_system_type *fs_type, 215static int mqueue_get_sb(struct file_system_type *fs_type,
211 int flags, const char *dev_name, 216 int flags, const char *dev_name,
212 void *data, struct vfsmount *mnt) 217 void *data, struct vfsmount *mnt)
213{ 218{
214 return get_sb_single(fs_type, flags, data, mqueue_fill_super, mnt); 219 if (!(flags & MS_KERNMOUNT))
220 data = current->nsproxy->ipc_ns;
221 return get_sb_ns(fs_type, flags, data, mqueue_fill_super, mnt);
215} 222}
216 223
217static void init_once(void *foo) 224static void init_once(void *foo)
@@ -242,11 +249,13 @@ static void mqueue_delete_inode(struct inode *inode)
242 struct user_struct *user; 249 struct user_struct *user;
243 unsigned long mq_bytes; 250 unsigned long mq_bytes;
244 int i; 251 int i;
252 struct ipc_namespace *ipc_ns;
245 253
246 if (S_ISDIR(inode->i_mode)) { 254 if (S_ISDIR(inode->i_mode)) {
247 clear_inode(inode); 255 clear_inode(inode);
248 return; 256 return;
249 } 257 }
258 ipc_ns = get_ns_from_inode(inode);
250 info = MQUEUE_I(inode); 259 info = MQUEUE_I(inode);
251 spin_lock(&info->lock); 260 spin_lock(&info->lock);
252 for (i = 0; i < info->attr.mq_curmsgs; i++) 261 for (i = 0; i < info->attr.mq_curmsgs; i++)
@@ -262,10 +271,19 @@ static void mqueue_delete_inode(struct inode *inode)
262 if (user) { 271 if (user) {
263 spin_lock(&mq_lock); 272 spin_lock(&mq_lock);
264 user->mq_bytes -= mq_bytes; 273 user->mq_bytes -= mq_bytes;
265 queues_count--; 274 /*
275 * get_ns_from_inode() ensures that the
276 * (ipc_ns = sb->s_fs_info) is either a valid ipc_ns
277 * to which we now hold a reference, or it is NULL.
278 * We can't put it here under mq_lock, though.
279 */
280 if (ipc_ns)
281 ipc_ns->mq_queues_count--;
266 spin_unlock(&mq_lock); 282 spin_unlock(&mq_lock);
267 free_uid(user); 283 free_uid(user);
268 } 284 }
285 if (ipc_ns)
286 put_ipc_ns(ipc_ns);
269} 287}
270 288
271static int mqueue_create(struct inode *dir, struct dentry *dentry, 289static int mqueue_create(struct inode *dir, struct dentry *dentry,
@@ -274,31 +292,41 @@ static int mqueue_create(struct inode *dir, struct dentry *dentry,
274 struct inode *inode; 292 struct inode *inode;
275 struct mq_attr *attr = dentry->d_fsdata; 293 struct mq_attr *attr = dentry->d_fsdata;
276 int error; 294 int error;
295 struct ipc_namespace *ipc_ns;
277 296
278 spin_lock(&mq_lock); 297 spin_lock(&mq_lock);
279 if (queues_count >= queues_max && !capable(CAP_SYS_RESOURCE)) { 298 ipc_ns = __get_ns_from_inode(dir);
299 if (!ipc_ns) {
300 error = -EACCES;
301 goto out_unlock;
302 }
303 if (ipc_ns->mq_queues_count >= ipc_ns->mq_queues_max &&
304 !capable(CAP_SYS_RESOURCE)) {
280 error = -ENOSPC; 305 error = -ENOSPC;
281 goto out_lock; 306 goto out_unlock;
282 } 307 }
283 queues_count++; 308 ipc_ns->mq_queues_count++;
284 spin_unlock(&mq_lock); 309 spin_unlock(&mq_lock);
285 310
286 inode = mqueue_get_inode(dir->i_sb, mode, attr); 311 inode = mqueue_get_inode(dir->i_sb, ipc_ns, mode, attr);
287 if (!inode) { 312 if (!inode) {
288 error = -ENOMEM; 313 error = -ENOMEM;
289 spin_lock(&mq_lock); 314 spin_lock(&mq_lock);
290 queues_count--; 315 ipc_ns->mq_queues_count--;
291 goto out_lock; 316 goto out_unlock;
292 } 317 }
293 318
319 put_ipc_ns(ipc_ns);
294 dir->i_size += DIRENT_SIZE; 320 dir->i_size += DIRENT_SIZE;
295 dir->i_ctime = dir->i_mtime = dir->i_atime = CURRENT_TIME; 321 dir->i_ctime = dir->i_mtime = dir->i_atime = CURRENT_TIME;
296 322
297 d_instantiate(dentry, inode); 323 d_instantiate(dentry, inode);
298 dget(dentry); 324 dget(dentry);
299 return 0; 325 return 0;
300out_lock: 326out_unlock:
301 spin_unlock(&mq_lock); 327 spin_unlock(&mq_lock);
328 if (ipc_ns)
329 put_ipc_ns(ipc_ns);
302 return error; 330 return error;
303} 331}
304 332
@@ -562,7 +590,7 @@ static void remove_notification(struct mqueue_inode_info *info)
562 info->notify_owner = NULL; 590 info->notify_owner = NULL;
563} 591}
564 592
565static int mq_attr_ok(struct mq_attr *attr) 593static int mq_attr_ok(struct ipc_namespace *ipc_ns, struct mq_attr *attr)
566{ 594{
567 if (attr->mq_maxmsg <= 0 || attr->mq_msgsize <= 0) 595 if (attr->mq_maxmsg <= 0 || attr->mq_msgsize <= 0)
568 return 0; 596 return 0;
@@ -570,8 +598,8 @@ static int mq_attr_ok(struct mq_attr *attr)
570 if (attr->mq_maxmsg > HARD_MSGMAX) 598 if (attr->mq_maxmsg > HARD_MSGMAX)
571 return 0; 599 return 0;
572 } else { 600 } else {
573 if (attr->mq_maxmsg > msg_max || 601 if (attr->mq_maxmsg > ipc_ns->mq_msg_max ||
574 attr->mq_msgsize > msgsize_max) 602 attr->mq_msgsize > ipc_ns->mq_msgsize_max)
575 return 0; 603 return 0;
576 } 604 }
577 /* check for overflow */ 605 /* check for overflow */
@@ -587,8 +615,9 @@ static int mq_attr_ok(struct mq_attr *attr)
587/* 615/*
588 * Invoked when creating a new queue via sys_mq_open 616 * Invoked when creating a new queue via sys_mq_open
589 */ 617 */
590static struct file *do_create(struct dentry *dir, struct dentry *dentry, 618static struct file *do_create(struct ipc_namespace *ipc_ns, struct dentry *dir,
591 int oflag, mode_t mode, struct mq_attr *attr) 619 struct dentry *dentry, int oflag, mode_t mode,
620 struct mq_attr *attr)
592{ 621{
593 const struct cred *cred = current_cred(); 622 const struct cred *cred = current_cred();
594 struct file *result; 623 struct file *result;
@@ -596,14 +625,14 @@ static struct file *do_create(struct dentry *dir, struct dentry *dentry,
596 625
597 if (attr) { 626 if (attr) {
598 ret = -EINVAL; 627 ret = -EINVAL;
599 if (!mq_attr_ok(attr)) 628 if (!mq_attr_ok(ipc_ns, attr))
600 goto out; 629 goto out;
601 /* store for use during create */ 630 /* store for use during create */
602 dentry->d_fsdata = attr; 631 dentry->d_fsdata = attr;
603 } 632 }
604 633
605 mode &= ~current->fs->umask; 634 mode &= ~current_umask();
606 ret = mnt_want_write(mqueue_mnt); 635 ret = mnt_want_write(ipc_ns->mq_mnt);
607 if (ret) 636 if (ret)
608 goto out; 637 goto out;
609 ret = vfs_create(dir->d_inode, dentry, mode, NULL); 638 ret = vfs_create(dir->d_inode, dentry, mode, NULL);
@@ -611,24 +640,25 @@ static struct file *do_create(struct dentry *dir, struct dentry *dentry,
611 if (ret) 640 if (ret)
612 goto out_drop_write; 641 goto out_drop_write;
613 642
614 result = dentry_open(dentry, mqueue_mnt, oflag, cred); 643 result = dentry_open(dentry, ipc_ns->mq_mnt, oflag, cred);
615 /* 644 /*
616 * dentry_open() took a persistent mnt_want_write(), 645 * dentry_open() took a persistent mnt_want_write(),
617 * so we can now drop this one. 646 * so we can now drop this one.
618 */ 647 */
619 mnt_drop_write(mqueue_mnt); 648 mnt_drop_write(ipc_ns->mq_mnt);
620 return result; 649 return result;
621 650
622out_drop_write: 651out_drop_write:
623 mnt_drop_write(mqueue_mnt); 652 mnt_drop_write(ipc_ns->mq_mnt);
624out: 653out:
625 dput(dentry); 654 dput(dentry);
626 mntput(mqueue_mnt); 655 mntput(ipc_ns->mq_mnt);
627 return ERR_PTR(ret); 656 return ERR_PTR(ret);
628} 657}
629 658
630/* Opens existing queue */ 659/* Opens existing queue */
631static struct file *do_open(struct dentry *dentry, int oflag) 660static struct file *do_open(struct ipc_namespace *ipc_ns,
661 struct dentry *dentry, int oflag)
632{ 662{
633 const struct cred *cred = current_cred(); 663 const struct cred *cred = current_cred();
634 664
@@ -637,17 +667,17 @@ static struct file *do_open(struct dentry *dentry, int oflag)
637 667
638 if ((oflag & O_ACCMODE) == (O_RDWR | O_WRONLY)) { 668 if ((oflag & O_ACCMODE) == (O_RDWR | O_WRONLY)) {
639 dput(dentry); 669 dput(dentry);
640 mntput(mqueue_mnt); 670 mntput(ipc_ns->mq_mnt);
641 return ERR_PTR(-EINVAL); 671 return ERR_PTR(-EINVAL);
642 } 672 }
643 673
644 if (inode_permission(dentry->d_inode, oflag2acc[oflag & O_ACCMODE])) { 674 if (inode_permission(dentry->d_inode, oflag2acc[oflag & O_ACCMODE])) {
645 dput(dentry); 675 dput(dentry);
646 mntput(mqueue_mnt); 676 mntput(ipc_ns->mq_mnt);
647 return ERR_PTR(-EACCES); 677 return ERR_PTR(-EACCES);
648 } 678 }
649 679
650 return dentry_open(dentry, mqueue_mnt, oflag, cred); 680 return dentry_open(dentry, ipc_ns->mq_mnt, oflag, cred);
651} 681}
652 682
653SYSCALL_DEFINE4(mq_open, const char __user *, u_name, int, oflag, mode_t, mode, 683SYSCALL_DEFINE4(mq_open, const char __user *, u_name, int, oflag, mode_t, mode,
@@ -658,6 +688,7 @@ SYSCALL_DEFINE4(mq_open, const char __user *, u_name, int, oflag, mode_t, mode,
658 char *name; 688 char *name;
659 struct mq_attr attr; 689 struct mq_attr attr;
660 int fd, error; 690 int fd, error;
691 struct ipc_namespace *ipc_ns = current->nsproxy->ipc_ns;
661 692
662 if (u_attr && copy_from_user(&attr, u_attr, sizeof(struct mq_attr))) 693 if (u_attr && copy_from_user(&attr, u_attr, sizeof(struct mq_attr)))
663 return -EFAULT; 694 return -EFAULT;
@@ -671,13 +702,13 @@ SYSCALL_DEFINE4(mq_open, const char __user *, u_name, int, oflag, mode_t, mode,
671 if (fd < 0) 702 if (fd < 0)
672 goto out_putname; 703 goto out_putname;
673 704
674 mutex_lock(&mqueue_mnt->mnt_root->d_inode->i_mutex); 705 mutex_lock(&ipc_ns->mq_mnt->mnt_root->d_inode->i_mutex);
675 dentry = lookup_one_len(name, mqueue_mnt->mnt_root, strlen(name)); 706 dentry = lookup_one_len(name, ipc_ns->mq_mnt->mnt_root, strlen(name));
676 if (IS_ERR(dentry)) { 707 if (IS_ERR(dentry)) {
677 error = PTR_ERR(dentry); 708 error = PTR_ERR(dentry);
678 goto out_err; 709 goto out_err;
679 } 710 }
680 mntget(mqueue_mnt); 711 mntget(ipc_ns->mq_mnt);
681 712
682 if (oflag & O_CREAT) { 713 if (oflag & O_CREAT) {
683 if (dentry->d_inode) { /* entry already exists */ 714 if (dentry->d_inode) { /* entry already exists */
@@ -685,10 +716,10 @@ SYSCALL_DEFINE4(mq_open, const char __user *, u_name, int, oflag, mode_t, mode,
685 error = -EEXIST; 716 error = -EEXIST;
686 if (oflag & O_EXCL) 717 if (oflag & O_EXCL)
687 goto out; 718 goto out;
688 filp = do_open(dentry, oflag); 719 filp = do_open(ipc_ns, dentry, oflag);
689 } else { 720 } else {
690 filp = do_create(mqueue_mnt->mnt_root, dentry, 721 filp = do_create(ipc_ns, ipc_ns->mq_mnt->mnt_root,
691 oflag, mode, 722 dentry, oflag, mode,
692 u_attr ? &attr : NULL); 723 u_attr ? &attr : NULL);
693 } 724 }
694 } else { 725 } else {
@@ -696,26 +727,27 @@ SYSCALL_DEFINE4(mq_open, const char __user *, u_name, int, oflag, mode_t, mode,
696 if (!dentry->d_inode) 727 if (!dentry->d_inode)
697 goto out; 728 goto out;
698 audit_inode(name, dentry); 729 audit_inode(name, dentry);
699 filp = do_open(dentry, oflag); 730 filp = do_open(ipc_ns, dentry, oflag);
700 } 731 }
701 732
702 if (IS_ERR(filp)) { 733 if (IS_ERR(filp)) {
703 error = PTR_ERR(filp); 734 error = PTR_ERR(filp);
704 goto out_putfd; 735 goto out_putfd;
705 } 736 }
737 ima_counts_get(filp);
706 738
707 fd_install(fd, filp); 739 fd_install(fd, filp);
708 goto out_upsem; 740 goto out_upsem;
709 741
710out: 742out:
711 dput(dentry); 743 dput(dentry);
712 mntput(mqueue_mnt); 744 mntput(ipc_ns->mq_mnt);
713out_putfd: 745out_putfd:
714 put_unused_fd(fd); 746 put_unused_fd(fd);
715out_err: 747out_err:
716 fd = error; 748 fd = error;
717out_upsem: 749out_upsem:
718 mutex_unlock(&mqueue_mnt->mnt_root->d_inode->i_mutex); 750 mutex_unlock(&ipc_ns->mq_mnt->mnt_root->d_inode->i_mutex);
719out_putname: 751out_putname:
720 putname(name); 752 putname(name);
721 return fd; 753 return fd;
@@ -727,14 +759,15 @@ SYSCALL_DEFINE1(mq_unlink, const char __user *, u_name)
727 char *name; 759 char *name;
728 struct dentry *dentry; 760 struct dentry *dentry;
729 struct inode *inode = NULL; 761 struct inode *inode = NULL;
762 struct ipc_namespace *ipc_ns = current->nsproxy->ipc_ns;
730 763
731 name = getname(u_name); 764 name = getname(u_name);
732 if (IS_ERR(name)) 765 if (IS_ERR(name))
733 return PTR_ERR(name); 766 return PTR_ERR(name);
734 767
735 mutex_lock_nested(&mqueue_mnt->mnt_root->d_inode->i_mutex, 768 mutex_lock_nested(&ipc_ns->mq_mnt->mnt_root->d_inode->i_mutex,
736 I_MUTEX_PARENT); 769 I_MUTEX_PARENT);
737 dentry = lookup_one_len(name, mqueue_mnt->mnt_root, strlen(name)); 770 dentry = lookup_one_len(name, ipc_ns->mq_mnt->mnt_root, strlen(name));
738 if (IS_ERR(dentry)) { 771 if (IS_ERR(dentry)) {
739 err = PTR_ERR(dentry); 772 err = PTR_ERR(dentry);
740 goto out_unlock; 773 goto out_unlock;
@@ -748,16 +781,16 @@ SYSCALL_DEFINE1(mq_unlink, const char __user *, u_name)
748 inode = dentry->d_inode; 781 inode = dentry->d_inode;
749 if (inode) 782 if (inode)
750 atomic_inc(&inode->i_count); 783 atomic_inc(&inode->i_count);
751 err = mnt_want_write(mqueue_mnt); 784 err = mnt_want_write(ipc_ns->mq_mnt);
752 if (err) 785 if (err)
753 goto out_err; 786 goto out_err;
754 err = vfs_unlink(dentry->d_parent->d_inode, dentry); 787 err = vfs_unlink(dentry->d_parent->d_inode, dentry);
755 mnt_drop_write(mqueue_mnt); 788 mnt_drop_write(ipc_ns->mq_mnt);
756out_err: 789out_err:
757 dput(dentry); 790 dput(dentry);
758 791
759out_unlock: 792out_unlock:
760 mutex_unlock(&mqueue_mnt->mnt_root->d_inode->i_mutex); 793 mutex_unlock(&ipc_ns->mq_mnt->mnt_root->d_inode->i_mutex);
761 putname(name); 794 putname(name);
762 if (inode) 795 if (inode)
763 iput(inode); 796 iput(inode);
@@ -1191,7 +1224,7 @@ static const struct file_operations mqueue_file_operations = {
1191 .read = mqueue_read_file, 1224 .read = mqueue_read_file,
1192}; 1225};
1193 1226
1194static struct super_operations mqueue_super_ops = { 1227static const struct super_operations mqueue_super_ops = {
1195 .alloc_inode = mqueue_alloc_inode, 1228 .alloc_inode = mqueue_alloc_inode,
1196 .destroy_inode = mqueue_destroy_inode, 1229 .destroy_inode = mqueue_destroy_inode,
1197 .statfs = simple_statfs, 1230 .statfs = simple_statfs,
@@ -1205,59 +1238,31 @@ static struct file_system_type mqueue_fs_type = {
1205 .kill_sb = kill_litter_super, 1238 .kill_sb = kill_litter_super,
1206}; 1239};
1207 1240
1208static int msg_max_limit_min = MIN_MSGMAX; 1241int mq_init_ns(struct ipc_namespace *ns)
1209static int msg_max_limit_max = MAX_MSGMAX; 1242{
1210 1243 ns->mq_queues_count = 0;
1211static int msg_maxsize_limit_min = MIN_MSGSIZEMAX; 1244 ns->mq_queues_max = DFLT_QUEUESMAX;
1212static int msg_maxsize_limit_max = MAX_MSGSIZEMAX; 1245 ns->mq_msg_max = DFLT_MSGMAX;
1213 1246 ns->mq_msgsize_max = DFLT_MSGSIZEMAX;
1214static ctl_table mq_sysctls[] = { 1247
1215 { 1248 ns->mq_mnt = kern_mount_data(&mqueue_fs_type, ns);
1216 .procname = "queues_max", 1249 if (IS_ERR(ns->mq_mnt)) {
1217 .data = &queues_max, 1250 int err = PTR_ERR(ns->mq_mnt);
1218 .maxlen = sizeof(int), 1251 ns->mq_mnt = NULL;
1219 .mode = 0644, 1252 return err;
1220 .proc_handler = &proc_dointvec, 1253 }
1221 }, 1254 return 0;
1222 { 1255}
1223 .procname = "msg_max",
1224 .data = &msg_max,
1225 .maxlen = sizeof(int),
1226 .mode = 0644,
1227 .proc_handler = &proc_dointvec_minmax,
1228 .extra1 = &msg_max_limit_min,
1229 .extra2 = &msg_max_limit_max,
1230 },
1231 {
1232 .procname = "msgsize_max",
1233 .data = &msgsize_max,
1234 .maxlen = sizeof(int),
1235 .mode = 0644,
1236 .proc_handler = &proc_dointvec_minmax,
1237 .extra1 = &msg_maxsize_limit_min,
1238 .extra2 = &msg_maxsize_limit_max,
1239 },
1240 { .ctl_name = 0 }
1241};
1242 1256
1243static ctl_table mq_sysctl_dir[] = { 1257void mq_clear_sbinfo(struct ipc_namespace *ns)
1244 { 1258{
1245 .procname = "mqueue", 1259 ns->mq_mnt->mnt_sb->s_fs_info = NULL;
1246 .mode = 0555, 1260}
1247 .child = mq_sysctls,
1248 },
1249 { .ctl_name = 0 }
1250};
1251 1261
1252static ctl_table mq_sysctl_root[] = { 1262void mq_put_mnt(struct ipc_namespace *ns)
1253 { 1263{
1254 .ctl_name = CTL_FS, 1264 mntput(ns->mq_mnt);
1255 .procname = "fs", 1265}
1256 .mode = 0555,
1257 .child = mq_sysctl_dir,
1258 },
1259 { .ctl_name = 0 }
1260};
1261 1266
1262static int __init init_mqueue_fs(void) 1267static int __init init_mqueue_fs(void)
1263{ 1268{
@@ -1270,21 +1275,20 @@ static int __init init_mqueue_fs(void)
1270 return -ENOMEM; 1275 return -ENOMEM;
1271 1276
1272 /* ignore failues - they are not fatal */ 1277 /* ignore failues - they are not fatal */
1273 mq_sysctl_table = register_sysctl_table(mq_sysctl_root); 1278 mq_sysctl_table = mq_register_sysctl_table();
1274 1279
1275 error = register_filesystem(&mqueue_fs_type); 1280 error = register_filesystem(&mqueue_fs_type);
1276 if (error) 1281 if (error)
1277 goto out_sysctl; 1282 goto out_sysctl;
1278 1283
1279 if (IS_ERR(mqueue_mnt = kern_mount(&mqueue_fs_type))) { 1284 spin_lock_init(&mq_lock);
1280 error = PTR_ERR(mqueue_mnt); 1285
1286 init_ipc_ns.mq_mnt = kern_mount_data(&mqueue_fs_type, &init_ipc_ns);
1287 if (IS_ERR(init_ipc_ns.mq_mnt)) {
1288 error = PTR_ERR(init_ipc_ns.mq_mnt);
1281 goto out_filesystem; 1289 goto out_filesystem;
1282 } 1290 }
1283 1291
1284 /* internal initialization - not common for vfs */
1285 queues_count = 0;
1286 spin_lock_init(&mq_lock);
1287
1288 return 0; 1292 return 0;
1289 1293
1290out_filesystem: 1294out_filesystem:
diff --git a/ipc/msgutil.c b/ipc/msgutil.c
index c82c215693d7..f095ee268833 100644
--- a/ipc/msgutil.c
+++ b/ipc/msgutil.c
@@ -13,10 +13,29 @@
13#include <linux/security.h> 13#include <linux/security.h>
14#include <linux/slab.h> 14#include <linux/slab.h>
15#include <linux/ipc.h> 15#include <linux/ipc.h>
16#include <linux/ipc_namespace.h>
16#include <asm/uaccess.h> 17#include <asm/uaccess.h>
17 18
18#include "util.h" 19#include "util.h"
19 20
21DEFINE_SPINLOCK(mq_lock);
22
23/*
24 * The next 2 defines are here bc this is the only file
25 * compiled when either CONFIG_SYSVIPC and CONFIG_POSIX_MQUEUE
26 * and not CONFIG_IPC_NS.
27 */
28struct ipc_namespace init_ipc_ns = {
29 .count = ATOMIC_INIT(1),
30#ifdef CONFIG_POSIX_MQUEUE
31 .mq_queues_max = DFLT_QUEUESMAX,
32 .mq_msg_max = DFLT_MSGMAX,
33 .mq_msgsize_max = DFLT_MSGSIZEMAX,
34#endif
35};
36
37atomic_t nr_ipc_ns = ATOMIC_INIT(1);
38
20struct msg_msgseg { 39struct msg_msgseg {
21 struct msg_msgseg* next; 40 struct msg_msgseg* next;
22 /* the next part of the message follows immediately */ 41 /* the next part of the message follows immediately */
diff --git a/ipc/namespace.c b/ipc/namespace.c
index 9171d948751e..a1094ff0befa 100644
--- a/ipc/namespace.c
+++ b/ipc/namespace.c
@@ -9,17 +9,26 @@
9#include <linux/rcupdate.h> 9#include <linux/rcupdate.h>
10#include <linux/nsproxy.h> 10#include <linux/nsproxy.h>
11#include <linux/slab.h> 11#include <linux/slab.h>
12#include <linux/fs.h>
13#include <linux/mount.h>
12 14
13#include "util.h" 15#include "util.h"
14 16
15static struct ipc_namespace *clone_ipc_ns(struct ipc_namespace *old_ns) 17static struct ipc_namespace *create_ipc_ns(void)
16{ 18{
17 struct ipc_namespace *ns; 19 struct ipc_namespace *ns;
20 int err;
18 21
19 ns = kmalloc(sizeof(struct ipc_namespace), GFP_KERNEL); 22 ns = kmalloc(sizeof(struct ipc_namespace), GFP_KERNEL);
20 if (ns == NULL) 23 if (ns == NULL)
21 return ERR_PTR(-ENOMEM); 24 return ERR_PTR(-ENOMEM);
22 25
26 atomic_set(&ns->count, 1);
27 err = mq_init_ns(ns);
28 if (err) {
29 kfree(ns);
30 return ERR_PTR(err);
31 }
23 atomic_inc(&nr_ipc_ns); 32 atomic_inc(&nr_ipc_ns);
24 33
25 sem_init_ns(ns); 34 sem_init_ns(ns);
@@ -34,24 +43,14 @@ static struct ipc_namespace *clone_ipc_ns(struct ipc_namespace *old_ns)
34 ipcns_notify(IPCNS_CREATED); 43 ipcns_notify(IPCNS_CREATED);
35 register_ipcns_notifier(ns); 44 register_ipcns_notifier(ns);
36 45
37 kref_init(&ns->kref);
38 return ns; 46 return ns;
39} 47}
40 48
41struct ipc_namespace *copy_ipcs(unsigned long flags, struct ipc_namespace *ns) 49struct ipc_namespace *copy_ipcs(unsigned long flags, struct ipc_namespace *ns)
42{ 50{
43 struct ipc_namespace *new_ns;
44
45 BUG_ON(!ns);
46 get_ipc_ns(ns);
47
48 if (!(flags & CLONE_NEWIPC)) 51 if (!(flags & CLONE_NEWIPC))
49 return ns; 52 return get_ipc_ns(ns);
50 53 return create_ipc_ns();
51 new_ns = clone_ipc_ns(ns);
52
53 put_ipc_ns(ns);
54 return new_ns;
55} 54}
56 55
57/* 56/*
@@ -84,11 +83,8 @@ void free_ipcs(struct ipc_namespace *ns, struct ipc_ids *ids,
84 up_write(&ids->rw_mutex); 83 up_write(&ids->rw_mutex);
85} 84}
86 85
87void free_ipc_ns(struct kref *kref) 86static void free_ipc_ns(struct ipc_namespace *ns)
88{ 87{
89 struct ipc_namespace *ns;
90
91 ns = container_of(kref, struct ipc_namespace, kref);
92 /* 88 /*
93 * Unregistering the hotplug notifier at the beginning guarantees 89 * Unregistering the hotplug notifier at the beginning guarantees
94 * that the ipc namespace won't be freed while we are inside the 90 * that the ipc namespace won't be freed while we are inside the
@@ -110,3 +106,29 @@ void free_ipc_ns(struct kref *kref)
110 */ 106 */
111 ipcns_notify(IPCNS_REMOVED); 107 ipcns_notify(IPCNS_REMOVED);
112} 108}
109
110/*
111 * put_ipc_ns - drop a reference to an ipc namespace.
112 * @ns: the namespace to put
113 *
114 * If this is the last task in the namespace exiting, and
115 * it is dropping the refcount to 0, then it can race with
116 * a task in another ipc namespace but in a mounts namespace
117 * which has this ipcns's mqueuefs mounted, doing some action
118 * with one of the mqueuefs files. That can raise the refcount.
119 * So dropping the refcount, and raising the refcount when
120 * accessing it through the VFS, are protected with mq_lock.
121 *
122 * (Clearly, a task raising the refcount on its own ipc_ns
123 * needn't take mq_lock since it can't race with the last task
124 * in the ipcns exiting).
125 */
126void put_ipc_ns(struct ipc_namespace *ns)
127{
128 if (atomic_dec_and_lock(&ns->count, &mq_lock)) {
129 mq_clear_sbinfo(ns);
130 spin_unlock(&mq_lock);
131 mq_put_mnt(ns);
132 free_ipc_ns(ns);
133 }
134}
diff --git a/ipc/sem.c b/ipc/sem.c
index 16a2189e96f9..87c2b641fd7b 100644
--- a/ipc/sem.c
+++ b/ipc/sem.c
@@ -1290,8 +1290,8 @@ void exit_sem(struct task_struct *tsk)
1290 int i; 1290 int i;
1291 1291
1292 rcu_read_lock(); 1292 rcu_read_lock();
1293 un = list_entry(rcu_dereference(ulp->list_proc.next), 1293 un = list_entry_rcu(ulp->list_proc.next,
1294 struct sem_undo, list_proc); 1294 struct sem_undo, list_proc);
1295 if (&un->list_proc == &ulp->list_proc) 1295 if (&un->list_proc == &ulp->list_proc)
1296 semid = -1; 1296 semid = -1;
1297 else 1297 else
diff --git a/ipc/shm.c b/ipc/shm.c
index f239d87e0d37..464694e0aa4a 100644
--- a/ipc/shm.c
+++ b/ipc/shm.c
@@ -55,7 +55,7 @@ struct shm_file_data {
55#define shm_file_data(file) (*((struct shm_file_data **)&(file)->private_data)) 55#define shm_file_data(file) (*((struct shm_file_data **)&(file)->private_data))
56 56
57static const struct file_operations shm_file_operations; 57static const struct file_operations shm_file_operations;
58static struct vm_operations_struct shm_vm_ops; 58static const struct vm_operations_struct shm_vm_ops;
59 59
60#define shm_ids(ns) ((ns)->ids[IPC_SHM_IDS]) 60#define shm_ids(ns) ((ns)->ids[IPC_SHM_IDS])
61 61
@@ -174,7 +174,7 @@ static void shm_destroy(struct ipc_namespace *ns, struct shmid_kernel *shp)
174 shm_unlock(shp); 174 shm_unlock(shp);
175 if (!is_file_hugepages(shp->shm_file)) 175 if (!is_file_hugepages(shp->shm_file))
176 shmem_lock(shp->shm_file, 0, shp->mlock_user); 176 shmem_lock(shp->shm_file, 0, shp->mlock_user);
177 else 177 else if (shp->mlock_user)
178 user_shm_unlock(shp->shm_file->f_path.dentry->d_inode->i_size, 178 user_shm_unlock(shp->shm_file->f_path.dentry->d_inode->i_size,
179 shp->mlock_user); 179 shp->mlock_user);
180 fput (shp->shm_file); 180 fput (shp->shm_file);
@@ -312,7 +312,7 @@ static const struct file_operations shm_file_operations = {
312 .get_unmapped_area = shm_get_unmapped_area, 312 .get_unmapped_area = shm_get_unmapped_area,
313}; 313};
314 314
315static struct vm_operations_struct shm_vm_ops = { 315static const struct vm_operations_struct shm_vm_ops = {
316 .open = shm_open, /* callback for a new vm-area open */ 316 .open = shm_open, /* callback for a new vm-area open */
317 .close = shm_close, /* callback for when the vm-area is released */ 317 .close = shm_close, /* callback for when the vm-area is released */
318 .fault = shm_fault, 318 .fault = shm_fault,
@@ -369,8 +369,8 @@ static int newseg(struct ipc_namespace *ns, struct ipc_params *params)
369 /* hugetlb_file_setup applies strict accounting */ 369 /* hugetlb_file_setup applies strict accounting */
370 if (shmflg & SHM_NORESERVE) 370 if (shmflg & SHM_NORESERVE)
371 acctflag = VM_NORESERVE; 371 acctflag = VM_NORESERVE;
372 file = hugetlb_file_setup(name, size, acctflag); 372 file = hugetlb_file_setup(name, size, acctflag,
373 shp->mlock_user = current_user(); 373 &shp->mlock_user, HUGETLB_SHMFS_INODE);
374 } else { 374 } else {
375 /* 375 /*
376 * Do not allow no accounting for OVERCOMMIT_NEVER, even 376 * Do not allow no accounting for OVERCOMMIT_NEVER, even
@@ -384,7 +384,6 @@ static int newseg(struct ipc_namespace *ns, struct ipc_params *params)
384 error = PTR_ERR(file); 384 error = PTR_ERR(file);
385 if (IS_ERR(file)) 385 if (IS_ERR(file))
386 goto no_file; 386 goto no_file;
387 ima_shm_check(file);
388 387
389 id = ipc_addid(&shm_ids(ns), &shp->shm_perm, ns->shm_ctlmni); 388 id = ipc_addid(&shm_ids(ns), &shp->shm_perm, ns->shm_ctlmni);
390 if (id < 0) { 389 if (id < 0) {
@@ -411,6 +410,8 @@ static int newseg(struct ipc_namespace *ns, struct ipc_params *params)
411 return error; 410 return error;
412 411
413no_id: 412no_id:
413 if (is_file_hugepages(file) && shp->mlock_user)
414 user_shm_unlock(size, shp->mlock_user);
414 fput(file); 415 fput(file);
415no_file: 416no_file:
416 security_shm_free(shp); 417 security_shm_free(shp);
@@ -555,12 +556,14 @@ static void shm_get_stat(struct ipc_namespace *ns, unsigned long *rss,
555 in_use = shm_ids(ns).in_use; 556 in_use = shm_ids(ns).in_use;
556 557
557 for (total = 0, next_id = 0; total < in_use; next_id++) { 558 for (total = 0, next_id = 0; total < in_use; next_id++) {
559 struct kern_ipc_perm *ipc;
558 struct shmid_kernel *shp; 560 struct shmid_kernel *shp;
559 struct inode *inode; 561 struct inode *inode;
560 562
561 shp = idr_find(&shm_ids(ns).ipcs_idr, next_id); 563 ipc = idr_find(&shm_ids(ns).ipcs_idr, next_id);
562 if (shp == NULL) 564 if (ipc == NULL)
563 continue; 565 continue;
566 shp = container_of(ipc, struct shmid_kernel, shm_perm);
564 567
565 inode = shp->shm_file->f_path.dentry->d_inode; 568 inode = shp->shm_file->f_path.dentry->d_inode;
566 569
@@ -889,7 +892,7 @@ long do_shmat(int shmid, char __user *shmaddr, int shmflg, ulong *raddr)
889 file = alloc_file(path.mnt, path.dentry, f_mode, &shm_file_operations); 892 file = alloc_file(path.mnt, path.dentry, f_mode, &shm_file_operations);
890 if (!file) 893 if (!file)
891 goto out_free; 894 goto out_free;
892 ima_shm_check(file); 895 ima_counts_get(file);
893 896
894 file->private_data = sfd; 897 file->private_data = sfd;
895 file->f_mapping = shp->shm_file->f_mapping; 898 file->f_mapping = shp->shm_file->f_mapping;
@@ -967,10 +970,13 @@ SYSCALL_DEFINE3(shmat, int, shmid, char __user *, shmaddr, int, shmflg)
967SYSCALL_DEFINE1(shmdt, char __user *, shmaddr) 970SYSCALL_DEFINE1(shmdt, char __user *, shmaddr)
968{ 971{
969 struct mm_struct *mm = current->mm; 972 struct mm_struct *mm = current->mm;
970 struct vm_area_struct *vma, *next; 973 struct vm_area_struct *vma;
971 unsigned long addr = (unsigned long)shmaddr; 974 unsigned long addr = (unsigned long)shmaddr;
972 loff_t size = 0;
973 int retval = -EINVAL; 975 int retval = -EINVAL;
976#ifdef CONFIG_MMU
977 loff_t size = 0;
978 struct vm_area_struct *next;
979#endif
974 980
975 if (addr & ~PAGE_MASK) 981 if (addr & ~PAGE_MASK)
976 return retval; 982 return retval;
diff --git a/ipc/util.c b/ipc/util.c
index 7585a72e259b..79ce84e890f7 100644
--- a/ipc/util.c
+++ b/ipc/util.c
@@ -47,15 +47,6 @@ struct ipc_proc_iface {
47 int (*show)(struct seq_file *, void *); 47 int (*show)(struct seq_file *, void *);
48}; 48};
49 49
50struct ipc_namespace init_ipc_ns = {
51 .kref = {
52 .refcount = ATOMIC_INIT(2),
53 },
54};
55
56atomic_t nr_ipc_ns = ATOMIC_INIT(1);
57
58
59#ifdef CONFIG_MEMORY_HOTPLUG 50#ifdef CONFIG_MEMORY_HOTPLUG
60 51
61static void ipc_memory_notifier(struct work_struct *work) 52static void ipc_memory_notifier(struct work_struct *work)
@@ -951,7 +942,7 @@ static int sysvipc_proc_show(struct seq_file *s, void *it)
951 return iface->show(s, it); 942 return iface->show(s, it);
952} 943}
953 944
954static struct seq_operations sysvipc_proc_seqops = { 945static const struct seq_operations sysvipc_proc_seqops = {
955 .start = sysvipc_proc_start, 946 .start = sysvipc_proc_start,
956 .stop = sysvipc_proc_stop, 947 .stop = sysvipc_proc_stop,
957 .next = sysvipc_proc_next, 948 .next = sysvipc_proc_next,
diff --git a/ipc/util.h b/ipc/util.h
index 3646b45a03c9..764b51a37a6a 100644
--- a/ipc/util.h
+++ b/ipc/util.h
@@ -10,6 +10,7 @@
10#ifndef _IPC_UTIL_H 10#ifndef _IPC_UTIL_H
11#define _IPC_UTIL_H 11#define _IPC_UTIL_H
12 12
13#include <linux/unistd.h>
13#include <linux/err.h> 14#include <linux/err.h>
14 15
15#define SEQ_MULTIPLIER (IPCMNI) 16#define SEQ_MULTIPLIER (IPCMNI)
@@ -20,6 +21,15 @@ void shm_init (void);
20 21
21struct ipc_namespace; 22struct ipc_namespace;
22 23
24#ifdef CONFIG_POSIX_MQUEUE
25extern void mq_clear_sbinfo(struct ipc_namespace *ns);
26extern void mq_put_mnt(struct ipc_namespace *ns);
27#else
28static inline void mq_clear_sbinfo(struct ipc_namespace *ns) { }
29static inline void mq_put_mnt(struct ipc_namespace *ns) { }
30#endif
31
32#ifdef CONFIG_SYSVIPC
23void sem_init_ns(struct ipc_namespace *ns); 33void sem_init_ns(struct ipc_namespace *ns);
24void msg_init_ns(struct ipc_namespace *ns); 34void msg_init_ns(struct ipc_namespace *ns);
25void shm_init_ns(struct ipc_namespace *ns); 35void shm_init_ns(struct ipc_namespace *ns);
@@ -27,6 +37,15 @@ void shm_init_ns(struct ipc_namespace *ns);
27void sem_exit_ns(struct ipc_namespace *ns); 37void sem_exit_ns(struct ipc_namespace *ns);
28void msg_exit_ns(struct ipc_namespace *ns); 38void msg_exit_ns(struct ipc_namespace *ns);
29void shm_exit_ns(struct ipc_namespace *ns); 39void shm_exit_ns(struct ipc_namespace *ns);
40#else
41static inline void sem_init_ns(struct ipc_namespace *ns) { }
42static inline void msg_init_ns(struct ipc_namespace *ns) { }
43static inline void shm_init_ns(struct ipc_namespace *ns) { }
44
45static inline void sem_exit_ns(struct ipc_namespace *ns) { }
46static inline void msg_exit_ns(struct ipc_namespace *ns) { }
47static inline void shm_exit_ns(struct ipc_namespace *ns) { }
48#endif
30 49
31/* 50/*
32 * Structure that holds the parameters needed by the ipc operations 51 * Structure that holds the parameters needed by the ipc operations
@@ -110,7 +129,7 @@ void ipc_update_perm(struct ipc64_perm *in, struct kern_ipc_perm *out);
110struct kern_ipc_perm *ipcctl_pre_down(struct ipc_ids *ids, int id, int cmd, 129struct kern_ipc_perm *ipcctl_pre_down(struct ipc_ids *ids, int id, int cmd,
111 struct ipc64_perm *perm, int extra_perm); 130 struct ipc64_perm *perm, int extra_perm);
112 131
113#if defined(__ia64__) || defined(__x86_64__) || defined(__hppa__) || defined(__XTENSA__) 132#ifndef __ARCH_WANT_IPC_PARSE_VERSION
114 /* On IA-64, we always use the "64-bit version" of the IPC structures. */ 133 /* On IA-64, we always use the "64-bit version" of the IPC structures. */
115# define ipc_parse_version(cmd) IPC_64 134# define ipc_parse_version(cmd) IPC_64
116#else 135#else
@@ -153,5 +172,6 @@ static inline void ipc_unlock(struct kern_ipc_perm *perm)
153struct kern_ipc_perm *ipc_lock_check(struct ipc_ids *ids, int id); 172struct kern_ipc_perm *ipc_lock_check(struct ipc_ids *ids, int id);
154int ipcget(struct ipc_namespace *ns, struct ipc_ids *ids, 173int ipcget(struct ipc_namespace *ns, struct ipc_ids *ids,
155 struct ipc_ops *ops, struct ipc_params *params); 174 struct ipc_ops *ops, struct ipc_params *params);
156 175void free_ipcs(struct ipc_namespace *ns, struct ipc_ids *ids,
176 void (*free)(struct ipc_namespace *, struct kern_ipc_perm *));
157#endif 177#endif