aboutsummaryrefslogtreecommitdiffstats
path: root/ipc/msg.c
diff options
context:
space:
mode:
Diffstat (limited to 'ipc/msg.c')
-rw-r--r--ipc/msg.c61
1 files changed, 17 insertions, 44 deletions
diff --git a/ipc/msg.c b/ipc/msg.c
index 08591a0278ce..c2ee26f01055 100644
--- a/ipc/msg.c
+++ b/ipc/msg.c
@@ -81,7 +81,7 @@ static struct ipc_ids init_msg_ids;
81 ipc_buildid(&msg_ids(ns), id, seq) 81 ipc_buildid(&msg_ids(ns), id, seq)
82 82
83static void freeque(struct ipc_namespace *, struct msg_queue *); 83static void freeque(struct ipc_namespace *, struct msg_queue *);
84static int newque (struct ipc_namespace *ns, key_t key, int msgflg); 84static int newque(struct ipc_namespace *, struct ipc_params *);
85#ifdef CONFIG_PROC_FS 85#ifdef CONFIG_PROC_FS
86static int sysvipc_msg_proc_show(struct seq_file *s, void *it); 86static int sysvipc_msg_proc_show(struct seq_file *s, void *it);
87#endif 87#endif
@@ -144,10 +144,12 @@ static inline void msg_rmid(struct ipc_namespace *ns, struct msg_queue *s)
144 ipc_rmid(&msg_ids(ns), &s->q_perm); 144 ipc_rmid(&msg_ids(ns), &s->q_perm);
145} 145}
146 146
147static int newque (struct ipc_namespace *ns, key_t key, int msgflg) 147static int newque(struct ipc_namespace *ns, struct ipc_params *params)
148{ 148{
149 struct msg_queue *msq; 149 struct msg_queue *msq;
150 int id, retval; 150 int id, retval;
151 key_t key = params->key;
152 int msgflg = params->flg;
151 153
152 msq = ipc_rcu_alloc(sizeof(*msq)); 154 msq = ipc_rcu_alloc(sizeof(*msq));
153 if (!msq) 155 if (!msq)
@@ -264,56 +266,27 @@ static void freeque(struct ipc_namespace *ns, struct msg_queue *msq)
264 ipc_rcu_putref(msq); 266 ipc_rcu_putref(msq);
265} 267}
266 268
269static inline int msg_security(void *msq, int msgflg)
270{
271 return security_msg_queue_associate((struct msg_queue *) msq, msgflg);
272}
273
267asmlinkage long sys_msgget(key_t key, int msgflg) 274asmlinkage long sys_msgget(key_t key, int msgflg)
268{ 275{
269 struct msg_queue *msq;
270 int ret;
271 struct ipc_namespace *ns; 276 struct ipc_namespace *ns;
277 struct ipc_ops msg_ops;
278 struct ipc_params msg_params;
272 279
273 ns = current->nsproxy->ipc_ns; 280 ns = current->nsproxy->ipc_ns;
274 281
275 ret = idr_pre_get(&msg_ids(ns).ipcs_idr, GFP_KERNEL); 282 msg_ops.getnew = newque;
283 msg_ops.associate = msg_security;
284 msg_ops.more_checks = NULL;
276 285
277 if (key == IPC_PRIVATE) { 286 msg_params.key = key;
278 if (!ret) 287 msg_params.flg = msgflg;
279 ret = -ENOMEM;
280 else {
281 mutex_lock(&msg_ids(ns).mutex);
282 ret = newque(ns, key, msgflg);
283 mutex_unlock(&msg_ids(ns).mutex);
284 }
285 } else {
286 mutex_lock(&msg_ids(ns).mutex);
287 msq = (struct msg_queue *) ipc_findkey(&msg_ids(ns), key);
288 if (msq == NULL) {
289 /* key not used */
290 if (!(msgflg & IPC_CREAT))
291 ret = -ENOENT;
292 else if (!ret)
293 ret = -ENOMEM;
294 else
295 ret = newque(ns, key, msgflg);
296 } else {
297 /* msq has been locked by ipc_findkey() */
298
299 if (msgflg & IPC_CREAT && msgflg & IPC_EXCL)
300 ret = -EEXIST;
301 else {
302 if (ipcperms(&msq->q_perm, msgflg))
303 ret = -EACCES;
304 else {
305 ret = security_msg_queue_associate(
306 msq, msgflg);
307 if (!ret)
308 ret = msq->q_perm.id;
309 }
310 }
311 msg_unlock(msq);
312 }
313 mutex_unlock(&msg_ids(ns).mutex);
314 }
315 288
316 return ret; 289 return ipcget(ns, &msg_ids(ns), &msg_ops, &msg_params);
317} 290}
318 291
319static inline unsigned long 292static inline unsigned long