xref: /linux/ipc/util.c (revision c537b994505099b7197e7d3125b942ecbcc51eb6)
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/smp_lock.h>
25 #include <linux/vmalloc.h>
26 #include <linux/slab.h>
27 #include <linux/capability.h>
28 #include <linux/highuid.h>
29 #include <linux/security.h>
30 #include <linux/rcupdate.h>
31 #include <linux/workqueue.h>
32 #include <linux/seq_file.h>
33 #include <linux/proc_fs.h>
34 #include <linux/audit.h>
35 #include <linux/nsproxy.h>
36 
37 #include <asm/unistd.h>
38 
39 #include "util.h"
40 
41 struct ipc_proc_iface {
42 	const char *path;
43 	const char *header;
44 	int ids;
45 	int (*show)(struct seq_file *, void *);
46 };
47 
48 struct ipc_namespace init_ipc_ns = {
49 	.kref = {
50 		.refcount	= ATOMIC_INIT(2),
51 	},
52 };
53 
54 #ifdef CONFIG_IPC_NS
55 static struct ipc_namespace *clone_ipc_ns(struct ipc_namespace *old_ns)
56 {
57 	int err;
58 	struct ipc_namespace *ns;
59 
60 	err = -ENOMEM;
61 	ns = kmalloc(sizeof(struct ipc_namespace), GFP_KERNEL);
62 	if (ns == NULL)
63 		goto err_mem;
64 
65 	err = sem_init_ns(ns);
66 	if (err)
67 		goto err_sem;
68 	err = msg_init_ns(ns);
69 	if (err)
70 		goto err_msg;
71 	err = shm_init_ns(ns);
72 	if (err)
73 		goto err_shm;
74 
75 	kref_init(&ns->kref);
76 	return ns;
77 
78 err_shm:
79 	msg_exit_ns(ns);
80 err_msg:
81 	sem_exit_ns(ns);
82 err_sem:
83 	kfree(ns);
84 err_mem:
85 	return ERR_PTR(err);
86 }
87 
88 int unshare_ipcs(unsigned long unshare_flags, struct ipc_namespace **new_ipc)
89 {
90 	struct ipc_namespace *new;
91 
92 	if (unshare_flags & CLONE_NEWIPC) {
93 		if (!capable(CAP_SYS_ADMIN))
94 			return -EPERM;
95 
96 		new = clone_ipc_ns(current->nsproxy->ipc_ns);
97 		if (IS_ERR(new))
98 			return PTR_ERR(new);
99 
100 		*new_ipc = new;
101 	}
102 
103 	return 0;
104 }
105 
106 int copy_ipcs(unsigned long flags, struct task_struct *tsk)
107 {
108 	struct ipc_namespace *old_ns = tsk->nsproxy->ipc_ns;
109 	struct ipc_namespace *new_ns;
110 	int err = 0;
111 
112 	if (!old_ns)
113 		return 0;
114 
115 	get_ipc_ns(old_ns);
116 
117 	if (!(flags & CLONE_NEWIPC))
118 		return 0;
119 
120 	if (!capable(CAP_SYS_ADMIN)) {
121 		err = -EPERM;
122 		goto out;
123 	}
124 
125 	new_ns = clone_ipc_ns(old_ns);
126 	if (!new_ns) {
127 		err = -ENOMEM;
128 		goto out;
129 	}
130 
131 	tsk->nsproxy->ipc_ns = new_ns;
132 out:
133 	put_ipc_ns(old_ns);
134 	return err;
135 }
136 
137 void free_ipc_ns(struct kref *kref)
138 {
139 	struct ipc_namespace *ns;
140 
141 	ns = container_of(kref, struct ipc_namespace, kref);
142 	sem_exit_ns(ns);
143 	msg_exit_ns(ns);
144 	shm_exit_ns(ns);
145 	kfree(ns);
146 }
147 #endif
148 
149 /**
150  *	ipc_init	-	initialise IPC subsystem
151  *
152  *	The various system5 IPC resources (semaphores, messages and shared
153  *	memory) are initialised
154  */
155 
156 static int __init ipc_init(void)
157 {
158 	sem_init();
159 	msg_init();
160 	shm_init();
161 	return 0;
162 }
163 __initcall(ipc_init);
164 
165 /**
166  *	ipc_init_ids		-	initialise IPC identifiers
167  *	@ids: Identifier set
168  *	@size: Number of identifiers
169  *
170  *	Given a size for the ipc identifier range (limited below IPCMNI)
171  *	set up the sequence range to use then allocate and initialise the
172  *	array itself.
173  */
174 
175 void __ipc_init ipc_init_ids(struct ipc_ids* ids, int size)
176 {
177 	int i;
178 
179 	mutex_init(&ids->mutex);
180 
181 	if(size > IPCMNI)
182 		size = IPCMNI;
183 	ids->in_use = 0;
184 	ids->max_id = -1;
185 	ids->seq = 0;
186 	{
187 		int seq_limit = INT_MAX/SEQ_MULTIPLIER;
188 		if(seq_limit > USHRT_MAX)
189 			ids->seq_max = USHRT_MAX;
190 		 else
191 		 	ids->seq_max = seq_limit;
192 	}
193 
194 	ids->entries = ipc_rcu_alloc(sizeof(struct kern_ipc_perm *)*size +
195 				     sizeof(struct ipc_id_ary));
196 
197 	if(ids->entries == NULL) {
198 		printk(KERN_ERR "ipc_init_ids() failed, ipc service disabled.\n");
199 		size = 0;
200 		ids->entries = &ids->nullentry;
201 	}
202 	ids->entries->size = size;
203 	for(i=0;i<size;i++)
204 		ids->entries->p[i] = NULL;
205 }
206 
207 #ifdef CONFIG_PROC_FS
208 static const struct file_operations sysvipc_proc_fops;
209 /**
210  *	ipc_init_proc_interface	-  Create a proc interface for sysipc types using a seq_file interface.
211  *	@path: Path in procfs
212  *	@header: Banner to be printed at the beginning of the file.
213  *	@ids: ipc id table to iterate.
214  *	@show: show routine.
215  */
216 void __init ipc_init_proc_interface(const char *path, const char *header,
217 		int ids, int (*show)(struct seq_file *, void *))
218 {
219 	struct proc_dir_entry *pde;
220 	struct ipc_proc_iface *iface;
221 
222 	iface = kmalloc(sizeof(*iface), GFP_KERNEL);
223 	if (!iface)
224 		return;
225 	iface->path	= path;
226 	iface->header	= header;
227 	iface->ids	= ids;
228 	iface->show	= show;
229 
230 	pde = create_proc_entry(path,
231 				S_IRUGO,        /* world readable */
232 				NULL            /* parent dir */);
233 	if (pde) {
234 		pde->data = iface;
235 		pde->proc_fops = &sysvipc_proc_fops;
236 	} else {
237 		kfree(iface);
238 	}
239 }
240 #endif
241 
242 /**
243  *	ipc_findkey	-	find a key in an ipc identifier set
244  *	@ids: Identifier set
245  *	@key: The key to find
246  *
247  *	Requires ipc_ids.mutex locked.
248  *	Returns the identifier if found or -1 if not.
249  */
250 
251 int ipc_findkey(struct ipc_ids* ids, key_t key)
252 {
253 	int id;
254 	struct kern_ipc_perm* p;
255 	int max_id = ids->max_id;
256 
257 	/*
258 	 * rcu_dereference() is not needed here
259 	 * since ipc_ids.mutex is held
260 	 */
261 	for (id = 0; id <= max_id; id++) {
262 		p = ids->entries->p[id];
263 		if(p==NULL)
264 			continue;
265 		if (key == p->key)
266 			return id;
267 	}
268 	return -1;
269 }
270 
271 /*
272  * Requires ipc_ids.mutex locked
273  */
274 static int grow_ary(struct ipc_ids* ids, int newsize)
275 {
276 	struct ipc_id_ary* new;
277 	struct ipc_id_ary* old;
278 	int i;
279 	int size = ids->entries->size;
280 
281 	if(newsize > IPCMNI)
282 		newsize = IPCMNI;
283 	if(newsize <= size)
284 		return newsize;
285 
286 	new = ipc_rcu_alloc(sizeof(struct kern_ipc_perm *)*newsize +
287 			    sizeof(struct ipc_id_ary));
288 	if(new == NULL)
289 		return size;
290 	new->size = newsize;
291 	memcpy(new->p, ids->entries->p, sizeof(struct kern_ipc_perm *)*size);
292 	for(i=size;i<newsize;i++) {
293 		new->p[i] = NULL;
294 	}
295 	old = ids->entries;
296 
297 	/*
298 	 * Use rcu_assign_pointer() to make sure the memcpyed contents
299 	 * of the new array are visible before the new array becomes visible.
300 	 */
301 	rcu_assign_pointer(ids->entries, new);
302 
303 	__ipc_fini_ids(ids, old);
304 	return newsize;
305 }
306 
307 /**
308  *	ipc_addid 	-	add an IPC identifier
309  *	@ids: IPC identifier set
310  *	@new: new IPC permission set
311  *	@size: new size limit for the id array
312  *
313  *	Add an entry 'new' to the IPC arrays. The permissions object is
314  *	initialised and the first free entry is set up and the id assigned
315  *	is returned. The list is returned in a locked state on success.
316  *	On failure the list is not locked and -1 is returned.
317  *
318  *	Called with ipc_ids.mutex held.
319  */
320 
321 int ipc_addid(struct ipc_ids* ids, struct kern_ipc_perm* new, int size)
322 {
323 	int id;
324 
325 	size = grow_ary(ids,size);
326 
327 	/*
328 	 * rcu_dereference()() is not needed here since
329 	 * ipc_ids.mutex is held
330 	 */
331 	for (id = 0; id < size; id++) {
332 		if(ids->entries->p[id] == NULL)
333 			goto found;
334 	}
335 	return -1;
336 found:
337 	ids->in_use++;
338 	if (id > ids->max_id)
339 		ids->max_id = id;
340 
341 	new->cuid = new->uid = current->euid;
342 	new->gid = new->cgid = current->egid;
343 
344 	new->seq = ids->seq++;
345 	if(ids->seq > ids->seq_max)
346 		ids->seq = 0;
347 
348 	spin_lock_init(&new->lock);
349 	new->deleted = 0;
350 	rcu_read_lock();
351 	spin_lock(&new->lock);
352 	ids->entries->p[id] = new;
353 	return id;
354 }
355 
356 /**
357  *	ipc_rmid	-	remove an IPC identifier
358  *	@ids: identifier set
359  *	@id: Identifier to remove
360  *
361  *	The identifier must be valid, and in use. The kernel will panic if
362  *	fed an invalid identifier. The entry is removed and internal
363  *	variables recomputed. The object associated with the identifier
364  *	is returned.
365  *	ipc_ids.mutex and the spinlock for this ID is hold before this function
366  *	is called, and remain locked on the exit.
367  */
368 
369 struct kern_ipc_perm* ipc_rmid(struct ipc_ids* ids, int id)
370 {
371 	struct kern_ipc_perm* p;
372 	int lid = id % SEQ_MULTIPLIER;
373 	BUG_ON(lid >= ids->entries->size);
374 
375 	/*
376 	 * do not need a rcu_dereference()() here to force ordering
377 	 * on Alpha, since the ipc_ids.mutex is held.
378 	 */
379 	p = ids->entries->p[lid];
380 	ids->entries->p[lid] = NULL;
381 	BUG_ON(p==NULL);
382 	ids->in_use--;
383 
384 	if (lid == ids->max_id) {
385 		do {
386 			lid--;
387 			if(lid == -1)
388 				break;
389 		} while (ids->entries->p[lid] == NULL);
390 		ids->max_id = lid;
391 	}
392 	p->deleted = 1;
393 	return p;
394 }
395 
396 /**
397  *	ipc_alloc	-	allocate ipc space
398  *	@size: size desired
399  *
400  *	Allocate memory from the appropriate pools and return a pointer to it.
401  *	NULL is returned if the allocation fails
402  */
403 
404 void* ipc_alloc(int size)
405 {
406 	void* out;
407 	if(size > PAGE_SIZE)
408 		out = vmalloc(size);
409 	else
410 		out = kmalloc(size, GFP_KERNEL);
411 	return out;
412 }
413 
414 /**
415  *	ipc_free        -       free ipc space
416  *	@ptr: pointer returned by ipc_alloc
417  *	@size: size of block
418  *
419  *	Free a block created with ipc_alloc(). The caller must know the size
420  *	used in the allocation call.
421  */
422 
423 void ipc_free(void* ptr, int size)
424 {
425 	if(size > PAGE_SIZE)
426 		vfree(ptr);
427 	else
428 		kfree(ptr);
429 }
430 
431 /*
432  * rcu allocations:
433  * There are three headers that are prepended to the actual allocation:
434  * - during use: ipc_rcu_hdr.
435  * - during the rcu grace period: ipc_rcu_grace.
436  * - [only if vmalloc]: ipc_rcu_sched.
437  * Their lifetime doesn't overlap, thus the headers share the same memory.
438  * Unlike a normal union, they are right-aligned, thus some container_of
439  * forward/backward casting is necessary:
440  */
441 struct ipc_rcu_hdr
442 {
443 	int refcount;
444 	int is_vmalloc;
445 	void *data[0];
446 };
447 
448 
449 struct ipc_rcu_grace
450 {
451 	struct rcu_head rcu;
452 	/* "void *" makes sure alignment of following data is sane. */
453 	void *data[0];
454 };
455 
456 struct ipc_rcu_sched
457 {
458 	struct work_struct work;
459 	/* "void *" makes sure alignment of following data is sane. */
460 	void *data[0];
461 };
462 
463 #define HDRLEN_KMALLOC		(sizeof(struct ipc_rcu_grace) > sizeof(struct ipc_rcu_hdr) ? \
464 					sizeof(struct ipc_rcu_grace) : sizeof(struct ipc_rcu_hdr))
465 #define HDRLEN_VMALLOC		(sizeof(struct ipc_rcu_sched) > HDRLEN_KMALLOC ? \
466 					sizeof(struct ipc_rcu_sched) : HDRLEN_KMALLOC)
467 
468 static inline int rcu_use_vmalloc(int size)
469 {
470 	/* Too big for a single page? */
471 	if (HDRLEN_KMALLOC + size > PAGE_SIZE)
472 		return 1;
473 	return 0;
474 }
475 
476 /**
477  *	ipc_rcu_alloc	-	allocate ipc and rcu space
478  *	@size: size desired
479  *
480  *	Allocate memory for the rcu header structure +  the object.
481  *	Returns the pointer to the object.
482  *	NULL is returned if the allocation fails.
483  */
484 
485 void* ipc_rcu_alloc(int size)
486 {
487 	void* out;
488 	/*
489 	 * We prepend the allocation with the rcu struct, and
490 	 * workqueue if necessary (for vmalloc).
491 	 */
492 	if (rcu_use_vmalloc(size)) {
493 		out = vmalloc(HDRLEN_VMALLOC + size);
494 		if (out) {
495 			out += HDRLEN_VMALLOC;
496 			container_of(out, struct ipc_rcu_hdr, data)->is_vmalloc = 1;
497 			container_of(out, struct ipc_rcu_hdr, data)->refcount = 1;
498 		}
499 	} else {
500 		out = kmalloc(HDRLEN_KMALLOC + size, GFP_KERNEL);
501 		if (out) {
502 			out += HDRLEN_KMALLOC;
503 			container_of(out, struct ipc_rcu_hdr, data)->is_vmalloc = 0;
504 			container_of(out, struct ipc_rcu_hdr, data)->refcount = 1;
505 		}
506 	}
507 
508 	return out;
509 }
510 
511 void ipc_rcu_getref(void *ptr)
512 {
513 	container_of(ptr, struct ipc_rcu_hdr, data)->refcount++;
514 }
515 
516 static void ipc_do_vfree(struct work_struct *work)
517 {
518 	vfree(container_of(work, struct ipc_rcu_sched, work));
519 }
520 
521 /**
522  * ipc_schedule_free - free ipc + rcu space
523  * @head: RCU callback structure for queued work
524  *
525  * Since RCU callback function is called in bh,
526  * we need to defer the vfree to schedule_work().
527  */
528 static void ipc_schedule_free(struct rcu_head *head)
529 {
530 	struct ipc_rcu_grace *grace =
531 		container_of(head, struct ipc_rcu_grace, rcu);
532 	struct ipc_rcu_sched *sched =
533 			container_of(&(grace->data[0]), struct ipc_rcu_sched, data[0]);
534 
535 	INIT_WORK(&sched->work, ipc_do_vfree);
536 	schedule_work(&sched->work);
537 }
538 
539 /**
540  * ipc_immediate_free - free ipc + rcu space
541  * @head: RCU callback structure that contains pointer to be freed
542  *
543  * Free from the RCU callback context.
544  */
545 static void ipc_immediate_free(struct rcu_head *head)
546 {
547 	struct ipc_rcu_grace *free =
548 		container_of(head, struct ipc_rcu_grace, rcu);
549 	kfree(free);
550 }
551 
552 void ipc_rcu_putref(void *ptr)
553 {
554 	if (--container_of(ptr, struct ipc_rcu_hdr, data)->refcount > 0)
555 		return;
556 
557 	if (container_of(ptr, struct ipc_rcu_hdr, data)->is_vmalloc) {
558 		call_rcu(&container_of(ptr, struct ipc_rcu_grace, data)->rcu,
559 				ipc_schedule_free);
560 	} else {
561 		call_rcu(&container_of(ptr, struct ipc_rcu_grace, data)->rcu,
562 				ipc_immediate_free);
563 	}
564 }
565 
566 /**
567  *	ipcperms	-	check IPC permissions
568  *	@ipcp: IPC permission set
569  *	@flag: desired permission set.
570  *
571  *	Check user, group, other permissions for access
572  *	to ipc resources. return 0 if allowed
573  */
574 
575 int ipcperms (struct kern_ipc_perm *ipcp, short flag)
576 {	/* flag will most probably be 0 or S_...UGO from <linux/stat.h> */
577 	int requested_mode, granted_mode, err;
578 
579 	if (unlikely((err = audit_ipc_obj(ipcp))))
580 		return err;
581 	requested_mode = (flag >> 6) | (flag >> 3) | flag;
582 	granted_mode = ipcp->mode;
583 	if (current->euid == ipcp->cuid || current->euid == ipcp->uid)
584 		granted_mode >>= 6;
585 	else if (in_group_p(ipcp->cgid) || in_group_p(ipcp->gid))
586 		granted_mode >>= 3;
587 	/* is there some bit set in requested_mode but not in granted_mode? */
588 	if ((requested_mode & ~granted_mode & 0007) &&
589 	    !capable(CAP_IPC_OWNER))
590 		return -1;
591 
592 	return security_ipc_permission(ipcp, flag);
593 }
594 
595 /*
596  * Functions to convert between the kern_ipc_perm structure and the
597  * old/new ipc_perm structures
598  */
599 
600 /**
601  *	kernel_to_ipc64_perm	-	convert kernel ipc permissions to user
602  *	@in: kernel permissions
603  *	@out: new style IPC permissions
604  *
605  *	Turn the kernel object @in into a set of permissions descriptions
606  *	for returning to userspace (@out).
607  */
608 
609 
610 void kernel_to_ipc64_perm (struct kern_ipc_perm *in, struct ipc64_perm *out)
611 {
612 	out->key	= in->key;
613 	out->uid	= in->uid;
614 	out->gid	= in->gid;
615 	out->cuid	= in->cuid;
616 	out->cgid	= in->cgid;
617 	out->mode	= in->mode;
618 	out->seq	= in->seq;
619 }
620 
621 /**
622  *	ipc64_perm_to_ipc_perm	-	convert old ipc permissions to new
623  *	@in: new style IPC permissions
624  *	@out: old style IPC permissions
625  *
626  *	Turn the new style permissions object @in into a compatibility
627  *	object and store it into the @out pointer.
628  */
629 
630 void ipc64_perm_to_ipc_perm (struct ipc64_perm *in, struct ipc_perm *out)
631 {
632 	out->key	= in->key;
633 	SET_UID(out->uid, in->uid);
634 	SET_GID(out->gid, in->gid);
635 	SET_UID(out->cuid, in->cuid);
636 	SET_GID(out->cgid, in->cgid);
637 	out->mode	= in->mode;
638 	out->seq	= in->seq;
639 }
640 
641 /*
642  * So far only shm_get_stat() calls ipc_get() via shm_get(), so ipc_get()
643  * is called with shm_ids.mutex locked.  Since grow_ary() is also called with
644  * shm_ids.mutex down(for Shared Memory), there is no need to add read
645  * barriers here to gurantee the writes in grow_ary() are seen in order
646  * here (for Alpha).
647  *
648  * However ipc_get() itself does not necessary require ipc_ids.mutex down. So
649  * if in the future ipc_get() is used by other places without ipc_ids.mutex
650  * down, then ipc_get() needs read memery barriers as ipc_lock() does.
651  */
652 struct kern_ipc_perm* ipc_get(struct ipc_ids* ids, int id)
653 {
654 	struct kern_ipc_perm* out;
655 	int lid = id % SEQ_MULTIPLIER;
656 	if(lid >= ids->entries->size)
657 		return NULL;
658 	out = ids->entries->p[lid];
659 	return out;
660 }
661 
662 struct kern_ipc_perm* ipc_lock(struct ipc_ids* ids, int id)
663 {
664 	struct kern_ipc_perm* out;
665 	int lid = id % SEQ_MULTIPLIER;
666 	struct ipc_id_ary* entries;
667 
668 	rcu_read_lock();
669 	entries = rcu_dereference(ids->entries);
670 	if(lid >= entries->size) {
671 		rcu_read_unlock();
672 		return NULL;
673 	}
674 	out = entries->p[lid];
675 	if(out == NULL) {
676 		rcu_read_unlock();
677 		return NULL;
678 	}
679 	spin_lock(&out->lock);
680 
681 	/* ipc_rmid() may have already freed the ID while ipc_lock
682 	 * was spinning: here verify that the structure is still valid
683 	 */
684 	if (out->deleted) {
685 		spin_unlock(&out->lock);
686 		rcu_read_unlock();
687 		return NULL;
688 	}
689 	return out;
690 }
691 
692 void ipc_lock_by_ptr(struct kern_ipc_perm *perm)
693 {
694 	rcu_read_lock();
695 	spin_lock(&perm->lock);
696 }
697 
698 void ipc_unlock(struct kern_ipc_perm* perm)
699 {
700 	spin_unlock(&perm->lock);
701 	rcu_read_unlock();
702 }
703 
704 int ipc_buildid(struct ipc_ids* ids, int id, int seq)
705 {
706 	return SEQ_MULTIPLIER*seq + id;
707 }
708 
709 int ipc_checkid(struct ipc_ids* ids, struct kern_ipc_perm* ipcp, int uid)
710 {
711 	if(uid/SEQ_MULTIPLIER != ipcp->seq)
712 		return 1;
713 	return 0;
714 }
715 
716 #ifdef __ARCH_WANT_IPC_PARSE_VERSION
717 
718 
719 /**
720  *	ipc_parse_version	-	IPC call version
721  *	@cmd: pointer to command
722  *
723  *	Return IPC_64 for new style IPC and IPC_OLD for old style IPC.
724  *	The @cmd value is turned from an encoding command and version into
725  *	just the command code.
726  */
727 
728 int ipc_parse_version (int *cmd)
729 {
730 	if (*cmd & IPC_64) {
731 		*cmd ^= IPC_64;
732 		return IPC_64;
733 	} else {
734 		return IPC_OLD;
735 	}
736 }
737 
738 #endif /* __ARCH_WANT_IPC_PARSE_VERSION */
739 
740 #ifdef CONFIG_PROC_FS
741 struct ipc_proc_iter {
742 	struct ipc_namespace *ns;
743 	struct ipc_proc_iface *iface;
744 };
745 
746 static void *sysvipc_proc_next(struct seq_file *s, void *it, loff_t *pos)
747 {
748 	struct ipc_proc_iter *iter = s->private;
749 	struct ipc_proc_iface *iface = iter->iface;
750 	struct kern_ipc_perm *ipc = it;
751 	loff_t p;
752 	struct ipc_ids *ids;
753 
754 	ids = iter->ns->ids[iface->ids];
755 
756 	/* If we had an ipc id locked before, unlock it */
757 	if (ipc && ipc != SEQ_START_TOKEN)
758 		ipc_unlock(ipc);
759 
760 	/*
761 	 * p = *pos - 1 (because id 0 starts at position 1)
762 	 *          + 1 (because we increment the position by one)
763 	 */
764 	for (p = *pos; p <= ids->max_id; p++) {
765 		if ((ipc = ipc_lock(ids, p)) != NULL) {
766 			*pos = p + 1;
767 			return ipc;
768 		}
769 	}
770 
771 	/* Out of range - return NULL to terminate iteration */
772 	return NULL;
773 }
774 
775 /*
776  * File positions: pos 0 -> header, pos n -> ipc id + 1.
777  * SeqFile iterator: iterator value locked shp or SEQ_TOKEN_START.
778  */
779 static void *sysvipc_proc_start(struct seq_file *s, loff_t *pos)
780 {
781 	struct ipc_proc_iter *iter = s->private;
782 	struct ipc_proc_iface *iface = iter->iface;
783 	struct kern_ipc_perm *ipc;
784 	loff_t p;
785 	struct ipc_ids *ids;
786 
787 	ids = iter->ns->ids[iface->ids];
788 
789 	/*
790 	 * Take the lock - this will be released by the corresponding
791 	 * call to stop().
792 	 */
793 	mutex_lock(&ids->mutex);
794 
795 	/* pos < 0 is invalid */
796 	if (*pos < 0)
797 		return NULL;
798 
799 	/* pos == 0 means header */
800 	if (*pos == 0)
801 		return SEQ_START_TOKEN;
802 
803 	/* Find the (pos-1)th ipc */
804 	for (p = *pos - 1; p <= ids->max_id; p++) {
805 		if ((ipc = ipc_lock(ids, p)) != NULL) {
806 			*pos = p + 1;
807 			return ipc;
808 		}
809 	}
810 	return NULL;
811 }
812 
813 static void sysvipc_proc_stop(struct seq_file *s, void *it)
814 {
815 	struct kern_ipc_perm *ipc = it;
816 	struct ipc_proc_iter *iter = s->private;
817 	struct ipc_proc_iface *iface = iter->iface;
818 	struct ipc_ids *ids;
819 
820 	/* If we had a locked segment, release it */
821 	if (ipc && ipc != SEQ_START_TOKEN)
822 		ipc_unlock(ipc);
823 
824 	ids = iter->ns->ids[iface->ids];
825 	/* Release the lock we took in start() */
826 	mutex_unlock(&ids->mutex);
827 }
828 
829 static int sysvipc_proc_show(struct seq_file *s, void *it)
830 {
831 	struct ipc_proc_iter *iter = s->private;
832 	struct ipc_proc_iface *iface = iter->iface;
833 
834 	if (it == SEQ_START_TOKEN)
835 		return seq_puts(s, iface->header);
836 
837 	return iface->show(s, it);
838 }
839 
840 static struct seq_operations sysvipc_proc_seqops = {
841 	.start = sysvipc_proc_start,
842 	.stop  = sysvipc_proc_stop,
843 	.next  = sysvipc_proc_next,
844 	.show  = sysvipc_proc_show,
845 };
846 
847 static int sysvipc_proc_open(struct inode *inode, struct file *file)
848 {
849 	int ret;
850 	struct seq_file *seq;
851 	struct ipc_proc_iter *iter;
852 
853 	ret = -ENOMEM;
854 	iter = kmalloc(sizeof(*iter), GFP_KERNEL);
855 	if (!iter)
856 		goto out;
857 
858 	ret = seq_open(file, &sysvipc_proc_seqops);
859 	if (ret)
860 		goto out_kfree;
861 
862 	seq = file->private_data;
863 	seq->private = iter;
864 
865 	iter->iface = PDE(inode)->data;
866 	iter->ns    = get_ipc_ns(current->nsproxy->ipc_ns);
867 out:
868 	return ret;
869 out_kfree:
870 	kfree(iter);
871 	goto out;
872 }
873 
874 static int sysvipc_proc_release(struct inode *inode, struct file *file)
875 {
876 	struct seq_file *seq = file->private_data;
877 	struct ipc_proc_iter *iter = seq->private;
878 	put_ipc_ns(iter->ns);
879 	return seq_release_private(inode, file);
880 }
881 
882 static const struct file_operations sysvipc_proc_fops = {
883 	.open    = sysvipc_proc_open,
884 	.read    = seq_read,
885 	.llseek  = seq_lseek,
886 	.release = sysvipc_proc_release,
887 };
888 #endif /* CONFIG_PROC_FS */
889