diff options
Diffstat (limited to 'ipc/util.c')
-rw-r--r-- | ipc/util.c | 290 |
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 | |||
122 | static int __init ipc_init(void) | 122 | static 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 | |||
141 | void ipc_init_ids(struct ipc_ids *ids) | 140 | void 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 |
160 | static const struct file_operations sysvipc_proc_fops; | 150 | static 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 | */ |
168 | void __init ipc_init_proc_interface(const char *path, const char *header, | 158 | void __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 | |||
204 | static struct kern_ipc_perm *ipc_findkey(struct ipc_ids *ids, key_t key) | 192 | static 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 | |||
236 | int ipc_get_maxid(struct ipc_ids *ids) | 223 | int 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 | */ |
273 | int ipc_addid(struct ipc_ids* ids, struct kern_ipc_perm* new, int size) | 260 | int 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 | */ |
332 | static int ipcget_new(struct ipc_namespace *ns, struct ipc_ids *ids, | 319 | static 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 | */ |
358 | static int ipc_check_perms(struct ipc_namespace *ns, | 345 | static 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 | */ |
390 | static int ipcget_public(struct ipc_namespace *ns, struct ipc_ids *ids, | 377 | static 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 | |||
442 | void ipc_rmid(struct ipc_ids *ids, struct kern_ipc_perm *ipcp) | 428 | void 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 | |||
463 | void *ipc_alloc(int size) | 444 | void *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 | 462 | void ipc_free(void *ptr, int size) | |
482 | void 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 | */ |
497 | void *ipc_rcu_alloc(int size) | 477 | void *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 | |||
548 | int ipcperms(struct ipc_namespace *ns, struct kern_ipc_perm *ipcp, short flag) | 527 | int 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 | 561 | void kernel_to_ipc64_perm(struct kern_ipc_perm *in, struct ipc64_perm *out) | |
583 | |||
584 | void 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 | 580 | void ipc64_perm_to_ipc_perm(struct ipc64_perm *in, struct ipc_perm *out) | |
604 | void 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 | 765 | int ipc_parse_version(int *cmd) | |
790 | int 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); |
938 | out: | 915 | out: |
939 | return ret; | 916 | return ret; |
940 | out_kfree: | ||
941 | kfree(iter); | ||
942 | goto out; | ||
943 | } | 917 | } |
944 | 918 | ||
945 | static int sysvipc_proc_release(struct inode *inode, struct file *file) | 919 | static int sysvipc_proc_release(struct inode *inode, struct file *file) |