1/*
2 * linux/ipc/util.c
3 * Copyright (C) 1992 Krishna Balasubramanian
4 *
5 * Sep 1997 - Call suser() last after "normal" permission checks so we
6 *            get BSD style process accounting right.
7 *            Occurs in several places in the IPC code.
8 *            Chris Evans, <chris@ferret.lmh.ox.ac.uk>
9 * Nov 1999 - ipc helper functions, unified SMP locking
10 *	      Manfred Spraul <manfred@colorfullife.com>
11 * Oct 2002 - One lock per IPC id. RCU ipc_free for lock-free grow_ary().
12 *            Mingming Cao <cmm@us.ibm.com>
13 * Mar 2006 - support for audit of ipc object properties
14 *            Dustin Kirkland <dustin.kirkland@us.ibm.com>
15 * Jun 2006 - namespaces ssupport
16 *            OpenVZ, SWsoft Inc.
17 *            Pavel Emelianov <xemul@openvz.org>
18 */
19
20#include <linux/mm.h>
21#include <linux/shm.h>
22#include <linux/init.h>
23#include <linux/msg.h>
24#include <linux/vmalloc.h>
25#include <linux/slab.h>
26#include <linux/capability.h>
27#include <linux/highuid.h>
28#include <linux/security.h>
29#include <linux/rcupdate.h>
30#include <linux/workqueue.h>
31#include <linux/seq_file.h>
32#include <linux/proc_fs.h>
33#include <linux/audit.h>
34#include <linux/nsproxy.h>
35#include <linux/rwsem.h>
36#include <linux/memory.h>
37#include <linux/ipc_namespace.h>
38
39#include <asm/unistd.h>
40
41#include "util.h"
42
43struct ipc_proc_iface {
44	const char *path;
45	const char *header;
46	int ids;
47	int (*show)(struct seq_file *, void *);
48};
49
50#ifdef CONFIG_MEMORY_HOTPLUG
51
52static void ipc_memory_notifier(struct work_struct *work)
53{
54	ipcns_notify(IPCNS_MEMCHANGED);
55}
56
57static DECLARE_WORK(ipc_memory_wq, ipc_memory_notifier);
58
59
60static int ipc_memory_callback(struct notifier_block *self,
61				unsigned long action, void *arg)
62{
63	switch (action) {
64	case MEM_ONLINE:    /* memory successfully brought online */
65	case MEM_OFFLINE:   /* or offline: it's time to recompute msgmni */
66		/*
67		 * This is done by invoking the ipcns notifier chain with the
68		 * IPC_MEMCHANGED event.
69		 * In order not to keep the lock on the hotplug memory chain
70		 * for too long, queue a work item that will, when waken up,
71		 * activate the ipcns notification chain.
72		 * No need to keep several ipc work items on the queue.
73		 */
74		if (!work_pending(&ipc_memory_wq))
75			schedule_work(&ipc_memory_wq);
76		break;
77	case MEM_GOING_ONLINE:
78	case MEM_GOING_OFFLINE:
79	case MEM_CANCEL_ONLINE:
80	case MEM_CANCEL_OFFLINE:
81	default:
82		break;
83	}
84
85	return NOTIFY_OK;
86}
87
88#endif /* CONFIG_MEMORY_HOTPLUG */
89
90/**
91 *	ipc_init	-	initialise IPC subsystem
92 *
93 *	The various system5 IPC resources (semaphores, messages and shared
94 *	memory) are initialised
95 *	A callback routine is registered into the memory hotplug notifier
96 *	chain: since msgmni scales to lowmem this callback routine will be
97 *	called upon successful memory add / remove to recompute msmgni.
98 */
99
100static int __init ipc_init(void)
101{
102	sem_init();
103	msg_init();
104	shm_init();
105	hotplug_memory_notifier(ipc_memory_callback, IPC_CALLBACK_PRI);
106	register_ipcns_notifier(&init_ipc_ns);
107	return 0;
108}
109__initcall(ipc_init);
110
111/**
112 *	ipc_init_ids		-	initialise IPC identifiers
113 *	@ids: Identifier set
114 *
115 *	Set up the sequence range to use for the ipc identifier range (limited
116 *	below IPCMNI) then initialise the ids idr.
117 */
118
119void ipc_init_ids(struct ipc_ids *ids)
120{
121	init_rwsem(&ids->rw_mutex);
122
123	ids->in_use = 0;
124	ids->seq = 0;
125	{
126		int seq_limit = INT_MAX/SEQ_MULTIPLIER;
127		if (seq_limit > USHRT_MAX)
128			ids->seq_max = USHRT_MAX;
129		 else
130		 	ids->seq_max = seq_limit;
131	}
132
133	idr_init(&ids->ipcs_idr);
134}
135
136#ifdef CONFIG_PROC_FS
137static const struct file_operations sysvipc_proc_fops;
138/**
139 *	ipc_init_proc_interface	-  Create a proc interface for sysipc types using a seq_file interface.
140 *	@path: Path in procfs
141 *	@header: Banner to be printed at the beginning of the file.
142 *	@ids: ipc id table to iterate.
143 *	@show: show routine.
144 */
145void __init ipc_init_proc_interface(const char *path, const char *header,
146		int ids, int (*show)(struct seq_file *, void *))
147{
148	struct proc_dir_entry *pde;
149	struct ipc_proc_iface *iface;
150
151	iface = kmalloc(sizeof(*iface), GFP_KERNEL);
152	if (!iface)
153		return;
154	iface->path	= path;
155	iface->header	= header;
156	iface->ids	= ids;
157	iface->show	= show;
158
159	pde = proc_create_data(path,
160			       S_IRUGO,        /* world readable */
161			       NULL,           /* parent dir */
162			       &sysvipc_proc_fops,
163			       iface);
164	if (!pde) {
165		kfree(iface);
166	}
167}
168#endif
169
170/**
171 *	ipc_findkey	-	find a key in an ipc identifier set
172 *	@ids: Identifier set
173 *	@key: The key to find
174 *
175 *	Requires ipc_ids.rw_mutex locked.
176 *	Returns the LOCKED pointer to the ipc structure if found or NULL
177 *	if not.
178 *	If key is found ipc points to the owning ipc structure
179 */
180
181static struct kern_ipc_perm *ipc_findkey(struct ipc_ids *ids, key_t key)
182{
183	struct kern_ipc_perm *ipc;
184	int next_id;
185	int total;
186
187	for (total = 0, next_id = 0; total < ids->in_use; next_id++) {
188		ipc = idr_find(&ids->ipcs_idr, next_id);
189
190		if (ipc == NULL)
191			continue;
192
193		if (ipc->key != key) {
194			total++;
195			continue;
196		}
197
198		ipc_lock_by_ptr(ipc);
199		return ipc;
200	}
201
202	return NULL;
203}
204
205/**
206 *	ipc_get_maxid 	-	get the last assigned id
207 *	@ids: IPC identifier set
208 *
209 *	Called with ipc_ids.rw_mutex held.
210 */
211
212int ipc_get_maxid(struct ipc_ids *ids)
213{
214	struct kern_ipc_perm *ipc;
215	int max_id = -1;
216	int total, id;
217
218	if (ids->in_use == 0)
219		return -1;
220
221	if (ids->in_use == IPCMNI)
222		return IPCMNI - 1;
223
224	/* Look for the last assigned id */
225	total = 0;
226	for (id = 0; id < IPCMNI && total < ids->in_use; id++) {
227		ipc = idr_find(&ids->ipcs_idr, id);
228		if (ipc != NULL) {
229			max_id = id;
230			total++;
231		}
232	}
233	return max_id;
234}
235
236/**
237 *	ipc_addid 	-	add an IPC identifier
238 *	@ids: IPC identifier set
239 *	@new: new IPC permission set
240 *	@size: limit for the number of used ids
241 *
242 *	Add an entry 'new' to the IPC ids idr. The permissions object is
243 *	initialised and the first free entry is set up and the id assigned
244 *	is returned. The 'new' entry is returned in a locked state on success.
245 *	On failure the entry is not locked and a negative err-code is returned.
246 *
247 *	Called with ipc_ids.rw_mutex held as a writer.
248 */
249
250int ipc_addid(struct ipc_ids* ids, struct kern_ipc_perm* new, int size)
251{
252	uid_t euid;
253	gid_t egid;
254	int id, err;
255
256	if (size > IPCMNI)
257		size = IPCMNI;
258
259	if (ids->in_use >= size)
260		return -ENOSPC;
261
262	spin_lock_init(&new->lock);
263	new->deleted = 0;
264	rcu_read_lock();
265	spin_lock(&new->lock);
266
267	err = idr_get_new(&ids->ipcs_idr, new, &id);
268	if (err) {
269		spin_unlock(&new->lock);
270		rcu_read_unlock();
271		return err;
272	}
273
274	ids->in_use++;
275
276	current_euid_egid(&euid, &egid);
277	new->cuid = new->uid = euid;
278	new->gid = new->cgid = egid;
279
280	new->seq = ids->seq++;
281	if(ids->seq > ids->seq_max)
282		ids->seq = 0;
283
284	new->id = ipc_buildid(id, new->seq);
285	return id;
286}
287
288/**
289 *	ipcget_new	-	create a new ipc object
290 *	@ns: namespace
291 *	@ids: IPC identifer set
292 *	@ops: the actual creation routine to call
293 *	@params: its parameters
294 *
295 *	This routine is called by sys_msgget, sys_semget() and sys_shmget()
296 *	when the key is IPC_PRIVATE.
297 */
298static int ipcget_new(struct ipc_namespace *ns, struct ipc_ids *ids,
299		struct ipc_ops *ops, struct ipc_params *params)
300{
301	int err;
302retry:
303	err = idr_pre_get(&ids->ipcs_idr, GFP_KERNEL);
304
305	if (!err)
306		return -ENOMEM;
307
308	down_write(&ids->rw_mutex);
309	err = ops->getnew(ns, params);
310	up_write(&ids->rw_mutex);
311
312	if (err == -EAGAIN)
313		goto retry;
314
315	return err;
316}
317
318/**
319 *	ipc_check_perms	-	check security and permissions for an IPC
320 *	@ipcp: ipc permission set
321 *	@ops: the actual security routine to call
322 *	@params: its parameters
323 *
324 *	This routine is called by sys_msgget(), sys_semget() and sys_shmget()
325 *      when the key is not IPC_PRIVATE and that key already exists in the
326 *      ids IDR.
327 *
328 *	On success, the IPC id is returned.
329 *
330 *	It is called with ipc_ids.rw_mutex and ipcp->lock held.
331 */
332static int ipc_check_perms(struct kern_ipc_perm *ipcp, struct ipc_ops *ops,
333			struct ipc_params *params)
334{
335	int err;
336
337	if (ipcperms(ipcp, params->flg))
338		err = -EACCES;
339	else {
340		err = ops->associate(ipcp, params->flg);
341		if (!err)
342			err = ipcp->id;
343	}
344
345	return err;
346}
347
348/**
349 *	ipcget_public	-	get an ipc object or create a new one
350 *	@ns: namespace
351 *	@ids: IPC identifer set
352 *	@ops: the actual creation routine to call
353 *	@params: its parameters
354 *
355 *	This routine is called by sys_msgget, sys_semget() and sys_shmget()
356 *	when the key is not IPC_PRIVATE.
357 *	It adds a new entry if the key is not found and does some permission
358 *      / security checkings if the key is found.
359 *
360 *	On success, the ipc id is returned.
361 */
362static int ipcget_public(struct ipc_namespace *ns, struct ipc_ids *ids,
363		struct ipc_ops *ops, struct ipc_params *params)
364{
365	struct kern_ipc_perm *ipcp;
366	int flg = params->flg;
367	int err;
368retry:
369	err = idr_pre_get(&ids->ipcs_idr, GFP_KERNEL);
370
371	/*
372	 * Take the lock as a writer since we are potentially going to add
373	 * a new entry + read locks are not "upgradable"
374	 */
375	down_write(&ids->rw_mutex);
376	ipcp = ipc_findkey(ids, params->key);
377	if (ipcp == NULL) {
378		/* key not used */
379		if (!(flg & IPC_CREAT))
380			err = -ENOENT;
381		else if (!err)
382			err = -ENOMEM;
383		else
384			err = ops->getnew(ns, params);
385	} else {
386		/* ipc object has been locked by ipc_findkey() */
387
388		if (flg & IPC_CREAT && flg & IPC_EXCL)
389			err = -EEXIST;
390		else {
391			err = 0;
392			if (ops->more_checks)
393				err = ops->more_checks(ipcp, params);
394			if (!err)
395				/*
396				 * ipc_check_perms returns the IPC id on
397				 * success
398				 */
399				err = ipc_check_perms(ipcp, ops, params);
400		}
401		ipc_unlock(ipcp);
402	}
403	up_write(&ids->rw_mutex);
404
405	if (err == -EAGAIN)
406		goto retry;
407
408	return err;
409}
410
411
412/**
413 *	ipc_rmid	-	remove an IPC identifier
414 *	@ids: IPC identifier set
415 *	@ipcp: ipc perm structure containing the identifier to remove
416 *
417 *	ipc_ids.rw_mutex (as a writer) and the spinlock for this ID are held
418 *	before this function is called, and remain locked on the exit.
419 */
420
421void ipc_rmid(struct ipc_ids *ids, struct kern_ipc_perm *ipcp)
422{
423	int lid = ipcid_to_idx(ipcp->id);
424
425	idr_remove(&ids->ipcs_idr, lid);
426
427	ids->in_use--;
428
429	ipcp->deleted = 1;
430
431	return;
432}
433
434/**
435 *	ipc_alloc	-	allocate ipc space
436 *	@size: size desired
437 *
438 *	Allocate memory from the appropriate pools and return a pointer to it.
439 *	NULL is returned if the allocation fails
440 */
441
442void* ipc_alloc(int size)
443{
444	void* out;
445	if(size > PAGE_SIZE)
446		out = vmalloc(size);
447	else
448		out = kmalloc(size, GFP_KERNEL);
449	return out;
450}
451
452/**
453 *	ipc_free        -       free ipc space
454 *	@ptr: pointer returned by ipc_alloc
455 *	@size: size of block
456 *
457 *	Free a block created with ipc_alloc(). The caller must know the size
458 *	used in the allocation call.
459 */
460
461void ipc_free(void* ptr, int size)
462{
463	if(size > PAGE_SIZE)
464		vfree(ptr);
465	else
466		kfree(ptr);
467}
468
469/*
470 * rcu allocations:
471 * There are three headers that are prepended to the actual allocation:
472 * - during use: ipc_rcu_hdr.
473 * - during the rcu grace period: ipc_rcu_grace.
474 * - [only if vmalloc]: ipc_rcu_sched.
475 * Their lifetime doesn't overlap, thus the headers share the same memory.
476 * Unlike a normal union, they are right-aligned, thus some container_of
477 * forward/backward casting is necessary:
478 */
479struct ipc_rcu_hdr
480{
481	int refcount;
482	int is_vmalloc;
483	void *data[0];
484};
485
486
487struct ipc_rcu_grace
488{
489	struct rcu_head rcu;
490	/* "void *" makes sure alignment of following data is sane. */
491	void *data[0];
492};
493
494struct ipc_rcu_sched
495{
496	struct work_struct work;
497	/* "void *" makes sure alignment of following data is sane. */
498	void *data[0];
499};
500
501#define HDRLEN_KMALLOC		(sizeof(struct ipc_rcu_grace) > sizeof(struct ipc_rcu_hdr) ? \
502					sizeof(struct ipc_rcu_grace) : sizeof(struct ipc_rcu_hdr))
503#define HDRLEN_VMALLOC		(sizeof(struct ipc_rcu_sched) > HDRLEN_KMALLOC ? \
504					sizeof(struct ipc_rcu_sched) : HDRLEN_KMALLOC)
505
506static inline int rcu_use_vmalloc(int size)
507{
508	/* Too big for a single page? */
509	if (HDRLEN_KMALLOC + size > PAGE_SIZE)
510		return 1;
511	return 0;
512}
513
514/**
515 *	ipc_rcu_alloc	-	allocate ipc and rcu space
516 *	@size: size desired
517 *
518 *	Allocate memory for the rcu header structure +  the object.
519 *	Returns the pointer to the object.
520 *	NULL is returned if the allocation fails.
521 */
522
523void* ipc_rcu_alloc(int size)
524{
525	void* out;
526	/*
527	 * We prepend the allocation with the rcu struct, and
528	 * workqueue if necessary (for vmalloc).
529	 */
530	if (rcu_use_vmalloc(size)) {
531		out = vmalloc(HDRLEN_VMALLOC + size);
532		if (out) {
533			out += HDRLEN_VMALLOC;
534			container_of(out, struct ipc_rcu_hdr, data)->is_vmalloc = 1;
535			container_of(out, struct ipc_rcu_hdr, data)->refcount = 1;
536		}
537	} else {
538		out = kmalloc(HDRLEN_KMALLOC + size, GFP_KERNEL);
539		if (out) {
540			out += HDRLEN_KMALLOC;
541			container_of(out, struct ipc_rcu_hdr, data)->is_vmalloc = 0;
542			container_of(out, struct ipc_rcu_hdr, data)->refcount = 1;
543		}
544	}
545
546	return out;
547}
548
549void ipc_rcu_getref(void *ptr)
550{
551	container_of(ptr, struct ipc_rcu_hdr, data)->refcount++;
552}
553
554static void ipc_do_vfree(struct work_struct *work)
555{
556	vfree(container_of(work, struct ipc_rcu_sched, work));
557}
558
559/**
560 * ipc_schedule_free - free ipc + rcu space
561 * @head: RCU callback structure for queued work
562 *
563 * Since RCU callback function is called in bh,
564 * we need to defer the vfree to schedule_work().
565 */
566static void ipc_schedule_free(struct rcu_head *head)
567{
568	struct ipc_rcu_grace *grace;
569	struct ipc_rcu_sched *sched;
570
571	grace = container_of(head, struct ipc_rcu_grace, rcu);
572	sched = container_of(&(grace->data[0]), struct ipc_rcu_sched,
573				data[0]);
574
575	INIT_WORK(&sched->work, ipc_do_vfree);
576	schedule_work(&sched->work);
577}
578
579/**
580 * ipc_immediate_free - free ipc + rcu space
581 * @head: RCU callback structure that contains pointer to be freed
582 *
583 * Free from the RCU callback context.
584 */
585static void ipc_immediate_free(struct rcu_head *head)
586{
587	struct ipc_rcu_grace *free =
588		container_of(head, struct ipc_rcu_grace, rcu);
589	kfree(free);
590}
591
592void ipc_rcu_putref(void *ptr)
593{
594	if (--container_of(ptr, struct ipc_rcu_hdr, data)->refcount > 0)
595		return;
596
597	if (container_of(ptr, struct ipc_rcu_hdr, data)->is_vmalloc) {
598		call_rcu(&container_of(ptr, struct ipc_rcu_grace, data)->rcu,
599				ipc_schedule_free);
600	} else {
601		call_rcu(&container_of(ptr, struct ipc_rcu_grace, data)->rcu,
602				ipc_immediate_free);
603	}
604}
605
606/**
607 *	ipcperms	-	check IPC permissions
608 *	@ipcp: IPC permission set
609 *	@flag: desired permission set.
610 *
611 *	Check user, group, other permissions for access
612 *	to ipc resources. return 0 if allowed
613 */
614
615int ipcperms (struct kern_ipc_perm *ipcp, short flag)
616{	/* flag will most probably be 0 or S_...UGO from <linux/stat.h> */
617	uid_t euid = current_euid();
618	int requested_mode, granted_mode;
619
620	audit_ipc_obj(ipcp);
621	requested_mode = (flag >> 6) | (flag >> 3) | flag;
622	granted_mode = ipcp->mode;
623	if (euid == ipcp->cuid ||
624	    euid == ipcp->uid)
625		granted_mode >>= 6;
626	else if (in_group_p(ipcp->cgid) || in_group_p(ipcp->gid))
627		granted_mode >>= 3;
628	/* is there some bit set in requested_mode but not in granted_mode? */
629	if ((requested_mode & ~granted_mode & 0007) &&
630	    !capable(CAP_IPC_OWNER))
631		return -1;
632
633	return security_ipc_permission(ipcp, flag);
634}
635
636/*
637 * Functions to convert between the kern_ipc_perm structure and the
638 * old/new ipc_perm structures
639 */
640
641/**
642 *	kernel_to_ipc64_perm	-	convert kernel ipc permissions to user
643 *	@in: kernel permissions
644 *	@out: new style IPC permissions
645 *
646 *	Turn the kernel object @in into a set of permissions descriptions
647 *	for returning to userspace (@out).
648 */
649
650
651void kernel_to_ipc64_perm (struct kern_ipc_perm *in, struct ipc64_perm *out)
652{
653	out->key	= in->key;
654	out->uid	= in->uid;
655	out->gid	= in->gid;
656	out->cuid	= in->cuid;
657	out->cgid	= in->cgid;
658	out->mode	= in->mode;
659	out->seq	= in->seq;
660}
661
662/**
663 *	ipc64_perm_to_ipc_perm	-	convert new ipc permissions to old
664 *	@in: new style IPC permissions
665 *	@out: old style IPC permissions
666 *
667 *	Turn the new style permissions object @in into a compatibility
668 *	object and store it into the @out pointer.
669 */
670
671void ipc64_perm_to_ipc_perm (struct ipc64_perm *in, struct ipc_perm *out)
672{
673	out->key	= in->key;
674	SET_UID(out->uid, in->uid);
675	SET_GID(out->gid, in->gid);
676	SET_UID(out->cuid, in->cuid);
677	SET_GID(out->cgid, in->cgid);
678	out->mode	= in->mode;
679	out->seq	= in->seq;
680}
681
682/**
683 * ipc_lock - Lock an ipc structure without rw_mutex held
684 * @ids: IPC identifier set
685 * @id: ipc id to look for
686 *
687 * Look for an id in the ipc ids idr and lock the associated ipc object.
688 *
689 * The ipc object is locked on exit.
690 */
691
692struct kern_ipc_perm *ipc_lock(struct ipc_ids *ids, int id)
693{
694	struct kern_ipc_perm *out;
695	int lid = ipcid_to_idx(id);
696
697	rcu_read_lock();
698	out = idr_find(&ids->ipcs_idr, lid);
699	if (out == NULL) {
700		rcu_read_unlock();
701		return ERR_PTR(-EINVAL);
702	}
703
704	spin_lock(&out->lock);
705
706	/* ipc_rmid() may have already freed the ID while ipc_lock
707	 * was spinning: here verify that the structure is still valid
708	 */
709	if (out->deleted) {
710		spin_unlock(&out->lock);
711		rcu_read_unlock();
712		return ERR_PTR(-EINVAL);
713	}
714
715	return out;
716}
717
718struct kern_ipc_perm *ipc_lock_check(struct ipc_ids *ids, int id)
719{
720	struct kern_ipc_perm *out;
721
722	out = ipc_lock(ids, id);
723	if (IS_ERR(out))
724		return out;
725
726	if (ipc_checkid(out, id)) {
727		ipc_unlock(out);
728		return ERR_PTR(-EIDRM);
729	}
730
731	return out;
732}
733
734/**
735 * ipcget - Common sys_*get() code
736 * @ns : namsepace
737 * @ids : IPC identifier set
738 * @ops : operations to be called on ipc object creation, permission checks
739 *        and further checks
740 * @params : the parameters needed by the previous operations.
741 *
742 * Common routine called by sys_msgget(), sys_semget() and sys_shmget().
743 */
744int ipcget(struct ipc_namespace *ns, struct ipc_ids *ids,
745			struct ipc_ops *ops, struct ipc_params *params)
746{
747	if (params->key == IPC_PRIVATE)
748		return ipcget_new(ns, ids, ops, params);
749	else
750		return ipcget_public(ns, ids, ops, params);
751}
752
753/**
754 * ipc_update_perm - update the permissions of an IPC.
755 * @in:  the permission given as input.
756 * @out: the permission of the ipc to set.
757 */
758void ipc_update_perm(struct ipc64_perm *in, struct kern_ipc_perm *out)
759{
760	out->uid = in->uid;
761	out->gid = in->gid;
762	out->mode = (out->mode & ~S_IRWXUGO)
763		| (in->mode & S_IRWXUGO);
764}
765
766/**
767 * ipcctl_pre_down - retrieve an ipc and check permissions for some IPC_XXX cmd
768 * @ids:  the table of ids where to look for the ipc
769 * @id:   the id of the ipc to retrieve
770 * @cmd:  the cmd to check
771 * @perm: the permission to set
772 * @extra_perm: one extra permission parameter used by msq
773 *
774 * This function does some common audit and permissions check for some IPC_XXX
775 * cmd and is called from semctl_down, shmctl_down and msgctl_down.
776 * It must be called without any lock held and
777 *  - retrieves the ipc with the given id in the given table.
778 *  - performs some audit and permission check, depending on the given cmd
779 *  - returns the ipc with both ipc and rw_mutex locks held in case of success
780 *    or an err-code without any lock held otherwise.
781 */
782struct kern_ipc_perm *ipcctl_pre_down(struct ipc_ids *ids, int id, int cmd,
783				      struct ipc64_perm *perm, int extra_perm)
784{
785	struct kern_ipc_perm *ipcp;
786	uid_t euid;
787	int err;
788
789	down_write(&ids->rw_mutex);
790	ipcp = ipc_lock_check(ids, id);
791	if (IS_ERR(ipcp)) {
792		err = PTR_ERR(ipcp);
793		goto out_up;
794	}
795
796	audit_ipc_obj(ipcp);
797	if (cmd == IPC_SET)
798		audit_ipc_set_perm(extra_perm, perm->uid,
799					 perm->gid, perm->mode);
800
801	euid = current_euid();
802	if (euid == ipcp->cuid ||
803	    euid == ipcp->uid  || capable(CAP_SYS_ADMIN))
804		return ipcp;
805
806	err = -EPERM;
807	ipc_unlock(ipcp);
808out_up:
809	up_write(&ids->rw_mutex);
810	return ERR_PTR(err);
811}
812
813#ifdef __ARCH_WANT_IPC_PARSE_VERSION
814
815
816/**
817 *	ipc_parse_version	-	IPC call version
818 *	@cmd: pointer to command
819 *
820 *	Return IPC_64 for new style IPC and IPC_OLD for old style IPC.
821 *	The @cmd value is turned from an encoding command and version into
822 *	just the command code.
823 */
824
825int ipc_parse_version (int *cmd)
826{
827	if (*cmd & IPC_64) {
828		*cmd ^= IPC_64;
829		return IPC_64;
830	} else {
831		return IPC_OLD;
832	}
833}
834
835#endif /* __ARCH_WANT_IPC_PARSE_VERSION */
836
837#ifdef CONFIG_PROC_FS
838struct ipc_proc_iter {
839	struct ipc_namespace *ns;
840	struct ipc_proc_iface *iface;
841};
842
843/*
844 * This routine locks the ipc structure found at least at position pos.
845 */
846static struct kern_ipc_perm *sysvipc_find_ipc(struct ipc_ids *ids, loff_t pos,
847					      loff_t *new_pos)
848{
849	struct kern_ipc_perm *ipc;
850	int total, id;
851
852	total = 0;
853	for (id = 0; id < pos && total < ids->in_use; id++) {
854		ipc = idr_find(&ids->ipcs_idr, id);
855		if (ipc != NULL)
856			total++;
857	}
858
859	if (total >= ids->in_use)
860		return NULL;
861
862	for ( ; pos < IPCMNI; pos++) {
863		ipc = idr_find(&ids->ipcs_idr, pos);
864		if (ipc != NULL) {
865			*new_pos = pos + 1;
866			ipc_lock_by_ptr(ipc);
867			return ipc;
868		}
869	}
870
871	/* Out of range - return NULL to terminate iteration */
872	return NULL;
873}
874
875static void *sysvipc_proc_next(struct seq_file *s, void *it, loff_t *pos)
876{
877	struct ipc_proc_iter *iter = s->private;
878	struct ipc_proc_iface *iface = iter->iface;
879	struct kern_ipc_perm *ipc = it;
880
881	/* If we had an ipc id locked before, unlock it */
882	if (ipc && ipc != SEQ_START_TOKEN)
883		ipc_unlock(ipc);
884
885	return sysvipc_find_ipc(&iter->ns->ids[iface->ids], *pos, pos);
886}
887
888/*
889 * File positions: pos 0 -> header, pos n -> ipc id = n - 1.
890 * SeqFile iterator: iterator value locked ipc pointer or SEQ_TOKEN_START.
891 */
892static void *sysvipc_proc_start(struct seq_file *s, loff_t *pos)
893{
894	struct ipc_proc_iter *iter = s->private;
895	struct ipc_proc_iface *iface = iter->iface;
896	struct ipc_ids *ids;
897
898	ids = &iter->ns->ids[iface->ids];
899
900	/*
901	 * Take the lock - this will be released by the corresponding
902	 * call to stop().
903	 */
904	down_read(&ids->rw_mutex);
905
906	/* pos < 0 is invalid */
907	if (*pos < 0)
908		return NULL;
909
910	/* pos == 0 means header */
911	if (*pos == 0)
912		return SEQ_START_TOKEN;
913
914	/* Find the (pos-1)th ipc */
915	return sysvipc_find_ipc(ids, *pos - 1, pos);
916}
917
918static void sysvipc_proc_stop(struct seq_file *s, void *it)
919{
920	struct kern_ipc_perm *ipc = it;
921	struct ipc_proc_iter *iter = s->private;
922	struct ipc_proc_iface *iface = iter->iface;
923	struct ipc_ids *ids;
924
925	/* If we had a locked structure, release it */
926	if (ipc && ipc != SEQ_START_TOKEN)
927		ipc_unlock(ipc);
928
929	ids = &iter->ns->ids[iface->ids];
930	/* Release the lock we took in start() */
931	up_read(&ids->rw_mutex);
932}
933
934static int sysvipc_proc_show(struct seq_file *s, void *it)
935{
936	struct ipc_proc_iter *iter = s->private;
937	struct ipc_proc_iface *iface = iter->iface;
938
939	if (it == SEQ_START_TOKEN)
940		return seq_puts(s, iface->header);
941
942	return iface->show(s, it);
943}
944
945static const struct seq_operations sysvipc_proc_seqops = {
946	.start = sysvipc_proc_start,
947	.stop  = sysvipc_proc_stop,
948	.next  = sysvipc_proc_next,
949	.show  = sysvipc_proc_show,
950};
951
952static int sysvipc_proc_open(struct inode *inode, struct file *file)
953{
954	int ret;
955	struct seq_file *seq;
956	struct ipc_proc_iter *iter;
957
958	ret = -ENOMEM;
959	iter = kmalloc(sizeof(*iter), GFP_KERNEL);
960	if (!iter)
961		goto out;
962
963	ret = seq_open(file, &sysvipc_proc_seqops);
964	if (ret)
965		goto out_kfree;
966
967	seq = file->private_data;
968	seq->private = iter;
969
970	iter->iface = PDE(inode)->data;
971	iter->ns    = get_ipc_ns(current->nsproxy->ipc_ns);
972out:
973	return ret;
974out_kfree:
975	kfree(iter);
976	goto out;
977}
978
979static int sysvipc_proc_release(struct inode *inode, struct file *file)
980{
981	struct seq_file *seq = file->private_data;
982	struct ipc_proc_iter *iter = seq->private;
983	put_ipc_ns(iter->ns);
984	return seq_release_private(inode, file);
985}
986
987static const struct file_operations sysvipc_proc_fops = {
988	.open    = sysvipc_proc_open,
989	.read    = seq_read,
990	.llseek  = seq_lseek,
991	.release = sysvipc_proc_release,
992};
993#endif /* CONFIG_PROC_FS */
994