aboutsummaryrefslogtreecommitdiffstats
path: root/ipc/util.c
diff options
context:
space:
mode:
Diffstat (limited to 'ipc/util.c')
-rw-r--r--ipc/util.c290
1 files changed, 132 insertions, 158 deletions
diff --git a/ipc/util.c b/ipc/util.c
index 3ae17a4ace5b..e1b4c6db8aa0 100644
--- a/ipc/util.c
+++ b/ipc/util.c
@@ -110,15 +110,15 @@ static struct notifier_block ipc_memory_nb = {
110}; 110};
111 111
112/** 112/**
113 * ipc_init - initialise IPC subsystem 113 * ipc_init - initialise ipc subsystem
114 * 114 *
115 * The various system5 IPC resources (semaphores, messages and shared 115 * The various sysv ipc resources (semaphores, messages and shared
116 * memory) are initialised 116 * memory) are initialised.
117 * A callback routine is registered into the memory hotplug notifier 117 *
118 * chain: since msgmni scales to lowmem this callback routine will be 118 * A callback routine is registered into the memory hotplug notifier
119 * called upon successful memory add / remove to recompute msmgni. 119 * chain: since msgmni scales to lowmem this callback routine will be
120 * called upon successful memory add / remove to recompute msmgni.
120 */ 121 */
121
122static int __init ipc_init(void) 122static int __init ipc_init(void)
123{ 123{
124 sem_init(); 124 sem_init();
@@ -131,39 +131,29 @@ static int __init ipc_init(void)
131__initcall(ipc_init); 131__initcall(ipc_init);
132 132
133/** 133/**
134 * ipc_init_ids - initialise IPC identifiers 134 * ipc_init_ids - initialise ipc identifiers
135 * @ids: Identifier set 135 * @ids: ipc identifier set
136 * 136 *
137 * Set up the sequence range to use for the ipc identifier range (limited 137 * Set up the sequence range to use for the ipc identifier range (limited
138 * below IPCMNI) then initialise the ids idr. 138 * below IPCMNI) then initialise the ids idr.
139 */ 139 */
140
141void ipc_init_ids(struct ipc_ids *ids) 140void ipc_init_ids(struct ipc_ids *ids)
142{ 141{
143 init_rwsem(&ids->rwsem);
144
145 ids->in_use = 0; 142 ids->in_use = 0;
146 ids->seq = 0; 143 ids->seq = 0;
147 ids->next_id = -1; 144 ids->next_id = -1;
148 { 145 init_rwsem(&ids->rwsem);
149 int seq_limit = INT_MAX/SEQ_MULTIPLIER;
150 if (seq_limit > USHRT_MAX)
151 ids->seq_max = USHRT_MAX;
152 else
153 ids->seq_max = seq_limit;
154 }
155
156 idr_init(&ids->ipcs_idr); 146 idr_init(&ids->ipcs_idr);
157} 147}
158 148
159#ifdef CONFIG_PROC_FS 149#ifdef CONFIG_PROC_FS
160static const struct file_operations sysvipc_proc_fops; 150static const struct file_operations sysvipc_proc_fops;
161/** 151/**
162 * ipc_init_proc_interface - Create a proc interface for sysipc types using a seq_file interface. 152 * ipc_init_proc_interface - create a proc interface for sysipc types using a seq_file interface.
163 * @path: Path in procfs 153 * @path: Path in procfs
164 * @header: Banner to be printed at the beginning of the file. 154 * @header: Banner to be printed at the beginning of the file.
165 * @ids: ipc id table to iterate. 155 * @ids: ipc id table to iterate.
166 * @show: show routine. 156 * @show: show routine.
167 */ 157 */
168void __init ipc_init_proc_interface(const char *path, const char *header, 158void __init ipc_init_proc_interface(const char *path, const char *header,
169 int ids, int (*show)(struct seq_file *, void *)) 159 int ids, int (*show)(struct seq_file *, void *))
@@ -184,23 +174,21 @@ void __init ipc_init_proc_interface(const char *path, const char *header,
184 NULL, /* parent dir */ 174 NULL, /* parent dir */
185 &sysvipc_proc_fops, 175 &sysvipc_proc_fops,
186 iface); 176 iface);
187 if (!pde) { 177 if (!pde)
188 kfree(iface); 178 kfree(iface);
189 }
190} 179}
191#endif 180#endif
192 181
193/** 182/**
194 * ipc_findkey - find a key in an ipc identifier set 183 * ipc_findkey - find a key in an ipc identifier set
195 * @ids: Identifier set 184 * @ids: ipc identifier set
196 * @key: The key to find 185 * @key: key to find
197 * 186 *
198 * Requires ipc_ids.rwsem locked. 187 * Returns the locked pointer to the ipc structure if found or NULL
199 * Returns the LOCKED pointer to the ipc structure if found or NULL 188 * otherwise. If key is found ipc points to the owning ipc structure
200 * if not. 189 *
201 * If key is found ipc points to the owning ipc structure 190 * Called with ipc_ids.rwsem held.
202 */ 191 */
203
204static struct kern_ipc_perm *ipc_findkey(struct ipc_ids *ids, key_t key) 192static struct kern_ipc_perm *ipc_findkey(struct ipc_ids *ids, key_t key)
205{ 193{
206 struct kern_ipc_perm *ipc; 194 struct kern_ipc_perm *ipc;
@@ -227,12 +215,11 @@ static struct kern_ipc_perm *ipc_findkey(struct ipc_ids *ids, key_t key)
227} 215}
228 216
229/** 217/**
230 * ipc_get_maxid - get the last assigned id 218 * ipc_get_maxid - get the last assigned id
231 * @ids: IPC identifier set 219 * @ids: ipc identifier set
232 * 220 *
233 * Called with ipc_ids.rwsem held. 221 * Called with ipc_ids.rwsem held.
234 */ 222 */
235
236int ipc_get_maxid(struct ipc_ids *ids) 223int ipc_get_maxid(struct ipc_ids *ids)
237{ 224{
238 struct kern_ipc_perm *ipc; 225 struct kern_ipc_perm *ipc;
@@ -258,19 +245,19 @@ int ipc_get_maxid(struct ipc_ids *ids)
258} 245}
259 246
260/** 247/**
261 * ipc_addid - add an IPC identifier 248 * ipc_addid - add an ipc identifier
262 * @ids: IPC identifier set 249 * @ids: ipc identifier set
263 * @new: new IPC permission set 250 * @new: new ipc permission set
264 * @size: limit for the number of used ids 251 * @size: limit for the number of used ids
265 * 252 *
266 * Add an entry 'new' to the IPC ids idr. The permissions object is 253 * Add an entry 'new' to the ipc ids idr. The permissions object is
267 * initialised and the first free entry is set up and the id assigned 254 * initialised and the first free entry is set up and the id assigned
268 * is returned. The 'new' entry is returned in a locked state on success. 255 * is returned. The 'new' entry is returned in a locked state on success.
269 * On failure the entry is not locked and a negative err-code is returned. 256 * On failure the entry is not locked and a negative err-code is returned.
270 * 257 *
271 * Called with writer ipc_ids.rwsem held. 258 * Called with writer ipc_ids.rwsem held.
272 */ 259 */
273int ipc_addid(struct ipc_ids* ids, struct kern_ipc_perm* new, int size) 260int ipc_addid(struct ipc_ids *ids, struct kern_ipc_perm *new, int size)
274{ 261{
275 kuid_t euid; 262 kuid_t euid;
276 kgid_t egid; 263 kgid_t egid;
@@ -286,7 +273,7 @@ int ipc_addid(struct ipc_ids* ids, struct kern_ipc_perm* new, int size)
286 idr_preload(GFP_KERNEL); 273 idr_preload(GFP_KERNEL);
287 274
288 spin_lock_init(&new->lock); 275 spin_lock_init(&new->lock);
289 new->deleted = 0; 276 new->deleted = false;
290 rcu_read_lock(); 277 rcu_read_lock();
291 spin_lock(&new->lock); 278 spin_lock(&new->lock);
292 279
@@ -308,7 +295,7 @@ int ipc_addid(struct ipc_ids* ids, struct kern_ipc_perm* new, int size)
308 295
309 if (next_id < 0) { 296 if (next_id < 0) {
310 new->seq = ids->seq++; 297 new->seq = ids->seq++;
311 if (ids->seq > ids->seq_max) 298 if (ids->seq > IPCID_SEQ_MAX)
312 ids->seq = 0; 299 ids->seq = 0;
313 } else { 300 } else {
314 new->seq = ipcid_to_seqx(next_id); 301 new->seq = ipcid_to_seqx(next_id);
@@ -320,14 +307,14 @@ int ipc_addid(struct ipc_ids* ids, struct kern_ipc_perm* new, int size)
320} 307}
321 308
322/** 309/**
323 * ipcget_new - create a new ipc object 310 * ipcget_new - create a new ipc object
324 * @ns: namespace 311 * @ns: ipc namespace
325 * @ids: IPC identifer set 312 * @ids: ipc identifer set
326 * @ops: the actual creation routine to call 313 * @ops: the actual creation routine to call
327 * @params: its parameters 314 * @params: its parameters
328 * 315 *
329 * This routine is called by sys_msgget, sys_semget() and sys_shmget() 316 * This routine is called by sys_msgget, sys_semget() and sys_shmget()
330 * when the key is IPC_PRIVATE. 317 * when the key is IPC_PRIVATE.
331 */ 318 */
332static int ipcget_new(struct ipc_namespace *ns, struct ipc_ids *ids, 319static int ipcget_new(struct ipc_namespace *ns, struct ipc_ids *ids,
333 struct ipc_ops *ops, struct ipc_params *params) 320 struct ipc_ops *ops, struct ipc_params *params)
@@ -341,19 +328,19 @@ static int ipcget_new(struct ipc_namespace *ns, struct ipc_ids *ids,
341} 328}
342 329
343/** 330/**
344 * ipc_check_perms - check security and permissions for an IPC 331 * ipc_check_perms - check security and permissions for an ipc object
345 * @ns: IPC namespace 332 * @ns: ipc namespace
346 * @ipcp: ipc permission set 333 * @ipcp: ipc permission set
347 * @ops: the actual security routine to call 334 * @ops: the actual security routine to call
348 * @params: its parameters 335 * @params: its parameters
349 * 336 *
350 * This routine is called by sys_msgget(), sys_semget() and sys_shmget() 337 * This routine is called by sys_msgget(), sys_semget() and sys_shmget()
351 * when the key is not IPC_PRIVATE and that key already exists in the 338 * when the key is not IPC_PRIVATE and that key already exists in the
352 * ids IDR. 339 * ds IDR.
353 * 340 *
354 * On success, the IPC id is returned. 341 * On success, the ipc id is returned.
355 * 342 *
356 * It is called with ipc_ids.rwsem and ipcp->lock held. 343 * It is called with ipc_ids.rwsem and ipcp->lock held.
357 */ 344 */
358static int ipc_check_perms(struct ipc_namespace *ns, 345static int ipc_check_perms(struct ipc_namespace *ns,
359 struct kern_ipc_perm *ipcp, 346 struct kern_ipc_perm *ipcp,
@@ -374,18 +361,18 @@ static int ipc_check_perms(struct ipc_namespace *ns,
374} 361}
375 362
376/** 363/**
377 * ipcget_public - get an ipc object or create a new one 364 * ipcget_public - get an ipc object or create a new one
378 * @ns: namespace 365 * @ns: ipc namespace
379 * @ids: IPC identifer set 366 * @ids: ipc identifer set
380 * @ops: the actual creation routine to call 367 * @ops: the actual creation routine to call
381 * @params: its parameters 368 * @params: its parameters
382 * 369 *
383 * This routine is called by sys_msgget, sys_semget() and sys_shmget() 370 * This routine is called by sys_msgget, sys_semget() and sys_shmget()
384 * when the key is not IPC_PRIVATE. 371 * when the key is not IPC_PRIVATE.
385 * It adds a new entry if the key is not found and does some permission 372 * It adds a new entry if the key is not found and does some permission
386 * / security checkings if the key is found. 373 * / security checkings if the key is found.
387 * 374 *
388 * On success, the ipc id is returned. 375 * On success, the ipc id is returned.
389 */ 376 */
390static int ipcget_public(struct ipc_namespace *ns, struct ipc_ids *ids, 377static int ipcget_public(struct ipc_namespace *ns, struct ipc_ids *ids,
391 struct ipc_ops *ops, struct ipc_params *params) 378 struct ipc_ops *ops, struct ipc_params *params)
@@ -431,39 +418,33 @@ static int ipcget_public(struct ipc_namespace *ns, struct ipc_ids *ids,
431 418
432 419
433/** 420/**
434 * ipc_rmid - remove an IPC identifier 421 * ipc_rmid - remove an ipc identifier
435 * @ids: IPC identifier set 422 * @ids: ipc identifier set
436 * @ipcp: ipc perm structure containing the identifier to remove 423 * @ipcp: ipc perm structure containing the identifier to remove
437 * 424 *
438 * ipc_ids.rwsem (as a writer) and the spinlock for this ID are held 425 * ipc_ids.rwsem (as a writer) and the spinlock for this ID are held
439 * before this function is called, and remain locked on the exit. 426 * before this function is called, and remain locked on the exit.
440 */ 427 */
441
442void ipc_rmid(struct ipc_ids *ids, struct kern_ipc_perm *ipcp) 428void ipc_rmid(struct ipc_ids *ids, struct kern_ipc_perm *ipcp)
443{ 429{
444 int lid = ipcid_to_idx(ipcp->id); 430 int lid = ipcid_to_idx(ipcp->id);
445 431
446 idr_remove(&ids->ipcs_idr, lid); 432 idr_remove(&ids->ipcs_idr, lid);
447
448 ids->in_use--; 433 ids->in_use--;
449 434 ipcp->deleted = true;
450 ipcp->deleted = 1;
451
452 return;
453} 435}
454 436
455/** 437/**
456 * ipc_alloc - allocate ipc space 438 * ipc_alloc - allocate ipc space
457 * @size: size desired 439 * @size: size desired
458 * 440 *
459 * Allocate memory from the appropriate pools and return a pointer to it. 441 * Allocate memory from the appropriate pools and return a pointer to it.
460 * NULL is returned if the allocation fails 442 * NULL is returned if the allocation fails
461 */ 443 */
462
463void *ipc_alloc(int size) 444void *ipc_alloc(int size)
464{ 445{
465 void *out; 446 void *out;
466 if(size > PAGE_SIZE) 447 if (size > PAGE_SIZE)
467 out = vmalloc(size); 448 out = vmalloc(size);
468 else 449 else
469 out = kmalloc(size, GFP_KERNEL); 450 out = kmalloc(size, GFP_KERNEL);
@@ -471,28 +452,27 @@ void *ipc_alloc(int size)
471} 452}
472 453
473/** 454/**
474 * ipc_free - free ipc space 455 * ipc_free - free ipc space
475 * @ptr: pointer returned by ipc_alloc 456 * @ptr: pointer returned by ipc_alloc
476 * @size: size of block 457 * @size: size of block
477 * 458 *
478 * Free a block created with ipc_alloc(). The caller must know the size 459 * Free a block created with ipc_alloc(). The caller must know the size
479 * used in the allocation call. 460 * used in the allocation call.
480 */ 461 */
481 462void ipc_free(void *ptr, int size)
482void ipc_free(void* ptr, int size)
483{ 463{
484 if(size > PAGE_SIZE) 464 if (size > PAGE_SIZE)
485 vfree(ptr); 465 vfree(ptr);
486 else 466 else
487 kfree(ptr); 467 kfree(ptr);
488} 468}
489 469
490/** 470/**
491 * ipc_rcu_alloc - allocate ipc and rcu space 471 * ipc_rcu_alloc - allocate ipc and rcu space
492 * @size: size desired 472 * @size: size desired
493 * 473 *
494 * Allocate memory for the rcu header structure + the object. 474 * Allocate memory for the rcu header structure + the object.
495 * Returns the pointer to the object or NULL upon failure. 475 * Returns the pointer to the object or NULL upon failure.
496 */ 476 */
497void *ipc_rcu_alloc(int size) 477void *ipc_rcu_alloc(int size)
498{ 478{
@@ -534,17 +514,16 @@ void ipc_rcu_free(struct rcu_head *head)
534} 514}
535 515
536/** 516/**
537 * ipcperms - check IPC permissions 517 * ipcperms - check ipc permissions
538 * @ns: IPC namespace 518 * @ns: ipc namespace
539 * @ipcp: IPC permission set 519 * @ipcp: ipc permission set
540 * @flag: desired permission set. 520 * @flag: desired permission set
541 * 521 *
542 * Check user, group, other permissions for access 522 * Check user, group, other permissions for access
543 * to ipc resources. return 0 if allowed 523 * to ipc resources. return 0 if allowed
544 * 524 *
545 * @flag will most probably be 0 or S_...UGO from <linux/stat.h> 525 * @flag will most probably be 0 or S_...UGO from <linux/stat.h>
546 */ 526 */
547
548int ipcperms(struct ipc_namespace *ns, struct kern_ipc_perm *ipcp, short flag) 527int ipcperms(struct ipc_namespace *ns, struct kern_ipc_perm *ipcp, short flag)
549{ 528{
550 kuid_t euid = current_euid(); 529 kuid_t euid = current_euid();
@@ -572,16 +551,14 @@ int ipcperms(struct ipc_namespace *ns, struct kern_ipc_perm *ipcp, short flag)
572 */ 551 */
573 552
574/** 553/**
575 * kernel_to_ipc64_perm - convert kernel ipc permissions to user 554 * kernel_to_ipc64_perm - convert kernel ipc permissions to user
576 * @in: kernel permissions 555 * @in: kernel permissions
577 * @out: new style IPC permissions 556 * @out: new style ipc permissions
578 * 557 *
579 * Turn the kernel object @in into a set of permissions descriptions 558 * Turn the kernel object @in into a set of permissions descriptions
580 * for returning to userspace (@out). 559 * for returning to userspace (@out).
581 */ 560 */
582 561void kernel_to_ipc64_perm(struct kern_ipc_perm *in, struct ipc64_perm *out)
583
584void kernel_to_ipc64_perm (struct kern_ipc_perm *in, struct ipc64_perm *out)
585{ 562{
586 out->key = in->key; 563 out->key = in->key;
587 out->uid = from_kuid_munged(current_user_ns(), in->uid); 564 out->uid = from_kuid_munged(current_user_ns(), in->uid);
@@ -593,15 +570,14 @@ void kernel_to_ipc64_perm (struct kern_ipc_perm *in, struct ipc64_perm *out)
593} 570}
594 571
595/** 572/**
596 * ipc64_perm_to_ipc_perm - convert new ipc permissions to old 573 * ipc64_perm_to_ipc_perm - convert new ipc permissions to old
597 * @in: new style IPC permissions 574 * @in: new style ipc permissions
598 * @out: old style IPC permissions 575 * @out: old style ipc permissions
599 * 576 *
600 * Turn the new style permissions object @in into a compatibility 577 * Turn the new style permissions object @in into a compatibility
601 * object and store it into the @out pointer. 578 * object and store it into the @out pointer.
602 */ 579 */
603 580void ipc64_perm_to_ipc_perm(struct ipc64_perm *in, struct ipc_perm *out)
604void ipc64_perm_to_ipc_perm (struct ipc64_perm *in, struct ipc_perm *out)
605{ 581{
606 out->key = in->key; 582 out->key = in->key;
607 SET_UID(out->uid, in->uid); 583 SET_UID(out->uid, in->uid);
@@ -635,8 +611,8 @@ struct kern_ipc_perm *ipc_obtain_object(struct ipc_ids *ids, int id)
635} 611}
636 612
637/** 613/**
638 * ipc_lock - Lock an ipc structure without rwsem held 614 * ipc_lock - lock an ipc structure without rwsem held
639 * @ids: IPC identifier set 615 * @ids: ipc identifier set
640 * @id: ipc id to look for 616 * @id: ipc id to look for
641 * 617 *
642 * Look for an id in the ipc ids idr and lock the associated ipc object. 618 * Look for an id in the ipc ids idr and lock the associated ipc object.
@@ -657,7 +633,7 @@ struct kern_ipc_perm *ipc_lock(struct ipc_ids *ids, int id)
657 /* ipc_rmid() may have already freed the ID while ipc_lock 633 /* ipc_rmid() may have already freed the ID while ipc_lock
658 * was spinning: here verify that the structure is still valid 634 * was spinning: here verify that the structure is still valid
659 */ 635 */
660 if (!out->deleted) 636 if (ipc_valid_object(out))
661 return out; 637 return out;
662 638
663 spin_unlock(&out->lock); 639 spin_unlock(&out->lock);
@@ -693,11 +669,11 @@ out:
693 669
694/** 670/**
695 * ipcget - Common sys_*get() code 671 * ipcget - Common sys_*get() code
696 * @ns : namsepace 672 * @ns: namsepace
697 * @ids : IPC identifier set 673 * @ids: ipc identifier set
698 * @ops : operations to be called on ipc object creation, permission checks 674 * @ops: operations to be called on ipc object creation, permission checks
699 * and further checks 675 * and further checks
700 * @params : the parameters needed by the previous operations. 676 * @params: the parameters needed by the previous operations.
701 * 677 *
702 * Common routine called by sys_msgget(), sys_semget() and sys_shmget(). 678 * Common routine called by sys_msgget(), sys_semget() and sys_shmget().
703 */ 679 */
@@ -711,7 +687,7 @@ int ipcget(struct ipc_namespace *ns, struct ipc_ids *ids,
711} 687}
712 688
713/** 689/**
714 * ipc_update_perm - update the permissions of an IPC. 690 * ipc_update_perm - update the permissions of an ipc object
715 * @in: the permission given as input. 691 * @in: the permission given as input.
716 * @out: the permission of the ipc to set. 692 * @out: the permission of the ipc to set.
717 */ 693 */
@@ -732,7 +708,7 @@ int ipc_update_perm(struct ipc64_perm *in, struct kern_ipc_perm *out)
732 708
733/** 709/**
734 * ipcctl_pre_down_nolock - retrieve an ipc and check permissions for some IPC_XXX cmd 710 * ipcctl_pre_down_nolock - retrieve an ipc and check permissions for some IPC_XXX cmd
735 * @ns: the ipc namespace 711 * @ns: ipc namespace
736 * @ids: the table of ids where to look for the ipc 712 * @ids: the table of ids where to look for the ipc
737 * @id: the id of the ipc to retrieve 713 * @id: the id of the ipc to retrieve
738 * @cmd: the cmd to check 714 * @cmd: the cmd to check
@@ -779,15 +755,14 @@ err:
779 755
780 756
781/** 757/**
782 * ipc_parse_version - IPC call version 758 * ipc_parse_version - ipc call version
783 * @cmd: pointer to command 759 * @cmd: pointer to command
784 * 760 *
785 * Return IPC_64 for new style IPC and IPC_OLD for old style IPC. 761 * Return IPC_64 for new style IPC and IPC_OLD for old style IPC.
786 * The @cmd value is turned from an encoding command and version into 762 * The @cmd value is turned from an encoding command and version into
787 * just the command code. 763 * just the command code.
788 */ 764 */
789 765int ipc_parse_version(int *cmd)
790int ipc_parse_version (int *cmd)
791{ 766{
792 if (*cmd & IPC_64) { 767 if (*cmd & IPC_64) {
793 *cmd ^= IPC_64; 768 *cmd ^= IPC_64;
@@ -824,7 +799,7 @@ static struct kern_ipc_perm *sysvipc_find_ipc(struct ipc_ids *ids, loff_t pos,
824 if (total >= ids->in_use) 799 if (total >= ids->in_use)
825 return NULL; 800 return NULL;
826 801
827 for ( ; pos < IPCMNI; pos++) { 802 for (; pos < IPCMNI; pos++) {
828 ipc = idr_find(&ids->ipcs_idr, pos); 803 ipc = idr_find(&ids->ipcs_idr, pos);
829 if (ipc != NULL) { 804 if (ipc != NULL) {
830 *new_pos = pos + 1; 805 *new_pos = pos + 1;
@@ -927,8 +902,10 @@ static int sysvipc_proc_open(struct inode *inode, struct file *file)
927 goto out; 902 goto out;
928 903
929 ret = seq_open(file, &sysvipc_proc_seqops); 904 ret = seq_open(file, &sysvipc_proc_seqops);
930 if (ret) 905 if (ret) {
931 goto out_kfree; 906 kfree(iter);
907 goto out;
908 }
932 909
933 seq = file->private_data; 910 seq = file->private_data;
934 seq->private = iter; 911 seq->private = iter;
@@ -937,9 +914,6 @@ static int sysvipc_proc_open(struct inode *inode, struct file *file)
937 iter->ns = get_ipc_ns(current->nsproxy->ipc_ns); 914 iter->ns = get_ipc_ns(current->nsproxy->ipc_ns);
938out: 915out:
939 return ret; 916 return ret;
940out_kfree:
941 kfree(iter);
942 goto out;
943} 917}
944 918
945static int sysvipc_proc_release(struct inode *inode, struct file *file) 919static int sysvipc_proc_release(struct inode *inode, struct file *file)