diff options
-rw-r--r-- | ipc/msg.c | 14 | ||||
-rw-r--r-- | ipc/sem.c | 14 | ||||
-rw-r--r-- | ipc/shm.c | 39 | ||||
-rw-r--r-- | ipc/util.c | 78 | ||||
-rw-r--r-- | ipc/util.h | 18 |
5 files changed, 118 insertions, 45 deletions
@@ -156,6 +156,13 @@ static inline void msg_rmid(struct ipc_namespace *ns, struct msg_queue *s) | |||
156 | ipc_rmid(&msg_ids(ns), &s->q_perm); | 156 | ipc_rmid(&msg_ids(ns), &s->q_perm); |
157 | } | 157 | } |
158 | 158 | ||
159 | /** | ||
160 | * newque - Create a new msg queue | ||
161 | * @ns: namespace | ||
162 | * @params: ptr to the structure that contains the key and msgflg | ||
163 | * | ||
164 | * Called with msg_ids.mutex held | ||
165 | */ | ||
159 | static int newque(struct ipc_namespace *ns, struct ipc_params *params) | 166 | static int newque(struct ipc_namespace *ns, struct ipc_params *params) |
160 | { | 167 | { |
161 | struct msg_queue *msq; | 168 | struct msg_queue *msq; |
@@ -250,8 +257,8 @@ static void expunge_all(struct msg_queue *msq, int res) | |||
250 | 257 | ||
251 | /* | 258 | /* |
252 | * freeque() wakes up waiters on the sender and receiver waiting queue, | 259 | * freeque() wakes up waiters on the sender and receiver waiting queue, |
253 | * removes the message queue from message queue ID | 260 | * removes the message queue from message queue ID IDR, and cleans up all the |
254 | * IDR, and cleans up all the messages associated with this queue. | 261 | * messages associated with this queue. |
255 | * | 262 | * |
256 | * msg_ids.mutex and the spinlock for this message queue are held | 263 | * msg_ids.mutex and the spinlock for this message queue are held |
257 | * before freeque() is called. msg_ids.mutex remains locked on exit. | 264 | * before freeque() is called. msg_ids.mutex remains locked on exit. |
@@ -278,6 +285,9 @@ static void freeque(struct ipc_namespace *ns, struct msg_queue *msq) | |||
278 | ipc_rcu_putref(msq); | 285 | ipc_rcu_putref(msq); |
279 | } | 286 | } |
280 | 287 | ||
288 | /* | ||
289 | * Called with msg_ids.mutex and ipcp locked. | ||
290 | */ | ||
281 | static inline int msg_security(struct kern_ipc_perm *ipcp, int msgflg) | 291 | static inline int msg_security(struct kern_ipc_perm *ipcp, int msgflg) |
282 | { | 292 | { |
283 | struct msg_queue *msq = container_of(ipcp, struct msg_queue, q_perm); | 293 | struct msg_queue *msq = container_of(ipcp, struct msg_queue, q_perm); |
@@ -228,6 +228,14 @@ static inline void sem_rmid(struct ipc_namespace *ns, struct sem_array *s) | |||
228 | */ | 228 | */ |
229 | #define IN_WAKEUP 1 | 229 | #define IN_WAKEUP 1 |
230 | 230 | ||
231 | /** | ||
232 | * newary - Create a new semaphore set | ||
233 | * @ns: namespace | ||
234 | * @params: ptr to the structure that contains key, semflg and nsems | ||
235 | * | ||
236 | * Called with sem_ids.mutex held | ||
237 | */ | ||
238 | |||
231 | static int newary(struct ipc_namespace *ns, struct ipc_params *params) | 239 | static int newary(struct ipc_namespace *ns, struct ipc_params *params) |
232 | { | 240 | { |
233 | int id; | 241 | int id; |
@@ -281,6 +289,9 @@ static int newary(struct ipc_namespace *ns, struct ipc_params *params) | |||
281 | } | 289 | } |
282 | 290 | ||
283 | 291 | ||
292 | /* | ||
293 | * Called with sem_ids.mutex and ipcp locked. | ||
294 | */ | ||
284 | static inline int sem_security(struct kern_ipc_perm *ipcp, int semflg) | 295 | static inline int sem_security(struct kern_ipc_perm *ipcp, int semflg) |
285 | { | 296 | { |
286 | struct sem_array *sma; | 297 | struct sem_array *sma; |
@@ -289,6 +300,9 @@ static inline int sem_security(struct kern_ipc_perm *ipcp, int semflg) | |||
289 | return security_sem_associate(sma, semflg); | 300 | return security_sem_associate(sma, semflg); |
290 | } | 301 | } |
291 | 302 | ||
303 | /* | ||
304 | * Called with sem_ids.mutex and ipcp locked. | ||
305 | */ | ||
292 | static inline int sem_more_checks(struct kern_ipc_perm *ipcp, | 306 | static inline int sem_more_checks(struct kern_ipc_perm *ipcp, |
293 | struct ipc_params *params) | 307 | struct ipc_params *params) |
294 | { | 308 | { |
@@ -82,6 +82,10 @@ static void __shm_init_ns(struct ipc_namespace *ns, struct ipc_ids *ids) | |||
82 | ipc_init_ids(ids); | 82 | ipc_init_ids(ids); |
83 | } | 83 | } |
84 | 84 | ||
85 | /* | ||
86 | * Called with shm_ids.mutex and the shp structure locked. | ||
87 | * Only shm_ids.mutex remains locked on exit. | ||
88 | */ | ||
85 | static void do_shm_rmid(struct ipc_namespace *ns, struct shmid_kernel *shp) | 89 | static void do_shm_rmid(struct ipc_namespace *ns, struct shmid_kernel *shp) |
86 | { | 90 | { |
87 | if (shp->shm_nattch){ | 91 | if (shp->shm_nattch){ |
@@ -182,6 +186,7 @@ static void shm_open(struct vm_area_struct *vma) | |||
182 | /* | 186 | /* |
183 | * shm_destroy - free the struct shmid_kernel | 187 | * shm_destroy - free the struct shmid_kernel |
184 | * | 188 | * |
189 | * @ns: namespace | ||
185 | * @shp: struct to free | 190 | * @shp: struct to free |
186 | * | 191 | * |
187 | * It has to be called with shp and shm_ids.mutex locked, | 192 | * It has to be called with shp and shm_ids.mutex locked, |
@@ -343,6 +348,14 @@ static struct vm_operations_struct shm_vm_ops = { | |||
343 | #endif | 348 | #endif |
344 | }; | 349 | }; |
345 | 350 | ||
351 | /** | ||
352 | * newseg - Create a new shared memory segment | ||
353 | * @ns: namespace | ||
354 | * @params: ptr to the structure that contains key, size and shmflg | ||
355 | * | ||
356 | * Called with shm_ids.mutex held | ||
357 | */ | ||
358 | |||
346 | static int newseg(struct ipc_namespace *ns, struct ipc_params *params) | 359 | static int newseg(struct ipc_namespace *ns, struct ipc_params *params) |
347 | { | 360 | { |
348 | key_t key = params->key; | 361 | key_t key = params->key; |
@@ -428,6 +441,9 @@ no_file: | |||
428 | return error; | 441 | return error; |
429 | } | 442 | } |
430 | 443 | ||
444 | /* | ||
445 | * Called with shm_ids.mutex and ipcp locked. | ||
446 | */ | ||
431 | static inline int shm_security(struct kern_ipc_perm *ipcp, int shmflg) | 447 | static inline int shm_security(struct kern_ipc_perm *ipcp, int shmflg) |
432 | { | 448 | { |
433 | struct shmid_kernel *shp; | 449 | struct shmid_kernel *shp; |
@@ -436,6 +452,9 @@ static inline int shm_security(struct kern_ipc_perm *ipcp, int shmflg) | |||
436 | return security_shm_associate(shp, shmflg); | 452 | return security_shm_associate(shp, shmflg); |
437 | } | 453 | } |
438 | 454 | ||
455 | /* | ||
456 | * Called with shm_ids.mutex and ipcp locked. | ||
457 | */ | ||
439 | static inline int shm_more_checks(struct kern_ipc_perm *ipcp, | 458 | static inline int shm_more_checks(struct kern_ipc_perm *ipcp, |
440 | struct ipc_params *params) | 459 | struct ipc_params *params) |
441 | { | 460 | { |
@@ -558,6 +577,9 @@ static inline unsigned long copy_shminfo_to_user(void __user *buf, struct shminf | |||
558 | } | 577 | } |
559 | } | 578 | } |
560 | 579 | ||
580 | /* | ||
581 | * Called with shm_ids.mutex held | ||
582 | */ | ||
561 | static void shm_get_stat(struct ipc_namespace *ns, unsigned long *rss, | 583 | static void shm_get_stat(struct ipc_namespace *ns, unsigned long *rss, |
562 | unsigned long *swp) | 584 | unsigned long *swp) |
563 | { | 585 | { |
@@ -573,18 +595,6 @@ static void shm_get_stat(struct ipc_namespace *ns, unsigned long *rss, | |||
573 | struct shmid_kernel *shp; | 595 | struct shmid_kernel *shp; |
574 | struct inode *inode; | 596 | struct inode *inode; |
575 | 597 | ||
576 | /* | ||
577 | * idr_find() is called via shm_get(), so with shm_ids.mutex | ||
578 | * locked. Since ipc_addid() is also called with | ||
579 | * shm_ids.mutex down, there is no need to add read barriers | ||
580 | * here to gurantee the writes in ipc_addid() are seen in | ||
581 | * order here (for Alpha). | ||
582 | * However idr_find() itself does not necessary require | ||
583 | * ipc_ids.mutex down. So if idr_find() is used by other | ||
584 | * places without ipc_ids.mutex down, then it needs read | ||
585 | * read memory barriers as ipc_lock() does. | ||
586 | */ | ||
587 | |||
588 | shp = idr_find(&shm_ids(ns).ipcs_idr, next_id); | 598 | shp = idr_find(&shm_ids(ns).ipcs_idr, next_id); |
589 | if (shp == NULL) | 599 | if (shp == NULL) |
590 | continue; | 600 | continue; |
@@ -638,8 +648,11 @@ asmlinkage long sys_shmctl (int shmid, int cmd, struct shmid_ds __user *buf) | |||
638 | shminfo.shmmin = SHMMIN; | 648 | shminfo.shmmin = SHMMIN; |
639 | if(copy_shminfo_to_user (buf, &shminfo, version)) | 649 | if(copy_shminfo_to_user (buf, &shminfo, version)) |
640 | return -EFAULT; | 650 | return -EFAULT; |
641 | /* reading a integer is always atomic */ | 651 | |
652 | mutex_lock(&shm_ids(ns).mutex); | ||
642 | err = ipc_get_maxid(&shm_ids(ns)); | 653 | err = ipc_get_maxid(&shm_ids(ns)); |
654 | mutex_unlock(&shm_ids(ns).mutex); | ||
655 | |||
643 | if(err<0) | 656 | if(err<0) |
644 | err = 0; | 657 | err = 0; |
645 | goto out; | 658 | goto out; |
diff --git a/ipc/util.c b/ipc/util.c index 49e75efe305b..fd29246dc3c8 100644 --- a/ipc/util.c +++ b/ipc/util.c | |||
@@ -194,7 +194,7 @@ void __init ipc_init_proc_interface(const char *path, const char *header, | |||
194 | * Requires ipc_ids.mutex locked. | 194 | * Requires ipc_ids.mutex locked. |
195 | * Returns the LOCKED pointer to the ipc structure if found or NULL | 195 | * Returns the LOCKED pointer to the ipc structure if found or NULL |
196 | * if not. | 196 | * if not. |
197 | * If key is found ipc contains its ipc structure | 197 | * If key is found ipc points to the owning ipc structure |
198 | */ | 198 | */ |
199 | 199 | ||
200 | static struct kern_ipc_perm *ipc_findkey(struct ipc_ids *ids, key_t key) | 200 | static struct kern_ipc_perm *ipc_findkey(struct ipc_ids *ids, key_t key) |
@@ -258,10 +258,10 @@ int ipc_get_maxid(struct ipc_ids *ids) | |||
258 | * @new: new IPC permission set | 258 | * @new: new IPC permission set |
259 | * @size: limit for the number of used ids | 259 | * @size: limit for the number of used ids |
260 | * | 260 | * |
261 | * Add an entry 'new' to the IPC idr. The permissions object is | 261 | * Add an entry 'new' to the IPC ids idr. The permissions object is |
262 | * initialised and the first free entry is set up and the id assigned | 262 | * initialised and the first free entry is set up and the id assigned |
263 | * is returned. The list is returned in a locked state on success. | 263 | * is returned. The 'new' entry is returned in a locked state on success. |
264 | * On failure the list is not locked and -1 is returned. | 264 | * On failure the entry is not locked and -1 is returned. |
265 | * | 265 | * |
266 | * Called with ipc_ids.mutex held. | 266 | * Called with ipc_ids.mutex held. |
267 | */ | 267 | */ |
@@ -270,10 +270,6 @@ int ipc_addid(struct ipc_ids* ids, struct kern_ipc_perm* new, int size) | |||
270 | { | 270 | { |
271 | int id, err; | 271 | int id, err; |
272 | 272 | ||
273 | /* | ||
274 | * rcu_dereference()() is not needed here since | ||
275 | * ipc_ids.mutex is held | ||
276 | */ | ||
277 | if (size > IPCMNI) | 273 | if (size > IPCMNI) |
278 | size = IPCMNI; | 274 | size = IPCMNI; |
279 | 275 | ||
@@ -303,12 +299,12 @@ int ipc_addid(struct ipc_ids* ids, struct kern_ipc_perm* new, int size) | |||
303 | /** | 299 | /** |
304 | * ipcget_new - create a new ipc object | 300 | * ipcget_new - create a new ipc object |
305 | * @ns: namespace | 301 | * @ns: namespace |
306 | * @ids: identifer set | 302 | * @ids: IPC identifer set |
307 | * @ops: the actual creation routine to call | 303 | * @ops: the actual creation routine to call |
308 | * @params: its parameters | 304 | * @params: its parameters |
309 | * | 305 | * |
310 | * This routine is called sys_msgget, sys_semget() and sys_shmget() when | 306 | * This routine is called by sys_msgget, sys_semget() and sys_shmget() |
311 | * the key is IPC_PRIVATE | 307 | * when the key is IPC_PRIVATE. |
312 | */ | 308 | */ |
313 | int ipcget_new(struct ipc_namespace *ns, struct ipc_ids *ids, | 309 | int ipcget_new(struct ipc_namespace *ns, struct ipc_ids *ids, |
314 | struct ipc_ops *ops, struct ipc_params *params) | 310 | struct ipc_ops *ops, struct ipc_params *params) |
@@ -330,9 +326,16 @@ int ipcget_new(struct ipc_namespace *ns, struct ipc_ids *ids, | |||
330 | /** | 326 | /** |
331 | * ipc_check_perms - check security and permissions for an IPC | 327 | * ipc_check_perms - check security and permissions for an IPC |
332 | * @ipcp: ipc permission set | 328 | * @ipcp: ipc permission set |
333 | * @ids: identifer set | ||
334 | * @ops: the actual security routine to call | 329 | * @ops: the actual security routine to call |
335 | * @params: its parameters | 330 | * @params: its parameters |
331 | * | ||
332 | * This routine is called by sys_msgget(), sys_semget() and sys_shmget() | ||
333 | * when the key is not IPC_PRIVATE and that key already exists in the | ||
334 | * ids IDR. | ||
335 | * | ||
336 | * On success, the IPC id is returned. | ||
337 | * | ||
338 | * It is called with ipc_ids.mutex and ipcp->lock held. | ||
336 | */ | 339 | */ |
337 | static int ipc_check_perms(struct kern_ipc_perm *ipcp, struct ipc_ops *ops, | 340 | static int ipc_check_perms(struct kern_ipc_perm *ipcp, struct ipc_ops *ops, |
338 | struct ipc_params *params) | 341 | struct ipc_params *params) |
@@ -353,12 +356,16 @@ static int ipc_check_perms(struct kern_ipc_perm *ipcp, struct ipc_ops *ops, | |||
353 | /** | 356 | /** |
354 | * ipcget_public - get an ipc object or create a new one | 357 | * ipcget_public - get an ipc object or create a new one |
355 | * @ns: namespace | 358 | * @ns: namespace |
356 | * @ids: identifer set | 359 | * @ids: IPC identifer set |
357 | * @ops: the actual creation routine to call | 360 | * @ops: the actual creation routine to call |
358 | * @params: its parameters | 361 | * @params: its parameters |
359 | * | 362 | * |
360 | * This routine is called sys_msgget, sys_semget() and sys_shmget() when | 363 | * This routine is called by sys_msgget, sys_semget() and sys_shmget() |
361 | * the key is not IPC_PRIVATE | 364 | * when the key is not IPC_PRIVATE. |
365 | * It adds a new entry if the key is not found and does some permission | ||
366 | * / security checkings if the key is found. | ||
367 | * | ||
368 | * On success, the ipc id is returned. | ||
362 | */ | 369 | */ |
363 | int ipcget_public(struct ipc_namespace *ns, struct ipc_ids *ids, | 370 | int ipcget_public(struct ipc_namespace *ns, struct ipc_ids *ids, |
364 | struct ipc_ops *ops, struct ipc_params *params) | 371 | struct ipc_ops *ops, struct ipc_params *params) |
@@ -389,6 +396,10 @@ int ipcget_public(struct ipc_namespace *ns, struct ipc_ids *ids, | |||
389 | if (ops->more_checks) | 396 | if (ops->more_checks) |
390 | err = ops->more_checks(ipcp, params); | 397 | err = ops->more_checks(ipcp, params); |
391 | if (!err) | 398 | if (!err) |
399 | /* | ||
400 | * ipc_check_perms returns the IPC id on | ||
401 | * success | ||
402 | */ | ||
392 | err = ipc_check_perms(ipcp, ops, params); | 403 | err = ipc_check_perms(ipcp, ops, params); |
393 | } | 404 | } |
394 | ipc_unlock(ipcp); | 405 | ipc_unlock(ipcp); |
@@ -401,12 +412,9 @@ int ipcget_public(struct ipc_namespace *ns, struct ipc_ids *ids, | |||
401 | 412 | ||
402 | /** | 413 | /** |
403 | * ipc_rmid - remove an IPC identifier | 414 | * ipc_rmid - remove an IPC identifier |
404 | * @ids: identifier set | 415 | * @ids: IPC identifier set |
405 | * @id: ipc perm structure containing the identifier to remove | 416 | * @ipcp: ipc perm structure containing the identifier to remove |
406 | * | 417 | * |
407 | * The identifier must be valid, and in use. The kernel will panic if | ||
408 | * fed an invalid identifier. The entry is removed and internal | ||
409 | * variables recomputed. | ||
410 | * ipc_ids.mutex and the spinlock for this ID are held before this | 418 | * ipc_ids.mutex and the spinlock for this ID are held before this |
411 | * function is called, and remain locked on the exit. | 419 | * function is called, and remain locked on the exit. |
412 | */ | 420 | */ |
@@ -558,10 +566,12 @@ static void ipc_do_vfree(struct work_struct *work) | |||
558 | */ | 566 | */ |
559 | static void ipc_schedule_free(struct rcu_head *head) | 567 | static void ipc_schedule_free(struct rcu_head *head) |
560 | { | 568 | { |
561 | struct ipc_rcu_grace *grace = | 569 | struct ipc_rcu_grace *grace; |
562 | container_of(head, struct ipc_rcu_grace, rcu); | 570 | struct ipc_rcu_sched *sched; |
563 | struct ipc_rcu_sched *sched = | 571 | |
564 | container_of(&(grace->data[0]), struct ipc_rcu_sched, data[0]); | 572 | grace = container_of(head, struct ipc_rcu_grace, rcu); |
573 | sched = container_of(&(grace->data[0]), struct ipc_rcu_sched, | ||
574 | data[0]); | ||
565 | 575 | ||
566 | INIT_WORK(&sched->work, ipc_do_vfree); | 576 | INIT_WORK(&sched->work, ipc_do_vfree); |
567 | schedule_work(&sched->work); | 577 | schedule_work(&sched->work); |
@@ -650,7 +660,7 @@ void kernel_to_ipc64_perm (struct kern_ipc_perm *in, struct ipc64_perm *out) | |||
650 | } | 660 | } |
651 | 661 | ||
652 | /** | 662 | /** |
653 | * ipc64_perm_to_ipc_perm - convert old ipc permissions to new | 663 | * ipc64_perm_to_ipc_perm - convert new ipc permissions to old |
654 | * @in: new style IPC permissions | 664 | * @in: new style IPC permissions |
655 | * @out: old style IPC permissions | 665 | * @out: old style IPC permissions |
656 | * | 666 | * |
@@ -669,6 +679,18 @@ void ipc64_perm_to_ipc_perm (struct ipc64_perm *in, struct ipc_perm *out) | |||
669 | out->seq = in->seq; | 679 | out->seq = in->seq; |
670 | } | 680 | } |
671 | 681 | ||
682 | /** | ||
683 | * ipc_lock - Lock an ipc structure | ||
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 | * ipc_ids.mutex is not necessarily held before this function is called, | ||
690 | * that's why we enter a RCU read section. | ||
691 | * The ipc object is locked on exit. | ||
692 | */ | ||
693 | |||
672 | struct kern_ipc_perm *ipc_lock(struct ipc_ids *ids, int id) | 694 | struct kern_ipc_perm *ipc_lock(struct ipc_ids *ids, int id) |
673 | { | 695 | { |
674 | struct kern_ipc_perm *out; | 696 | struct kern_ipc_perm *out; |
@@ -771,8 +793,8 @@ static void *sysvipc_proc_next(struct seq_file *s, void *it, loff_t *pos) | |||
771 | } | 793 | } |
772 | 794 | ||
773 | /* | 795 | /* |
774 | * File positions: pos 0 -> header, pos n -> ipc id + 1. | 796 | * File positions: pos 0 -> header, pos n -> ipc id = n - 1. |
775 | * SeqFile iterator: iterator value locked shp or SEQ_TOKEN_START. | 797 | * SeqFile iterator: iterator value locked ipc pointer or SEQ_TOKEN_START. |
776 | */ | 798 | */ |
777 | static void *sysvipc_proc_start(struct seq_file *s, loff_t *pos) | 799 | static void *sysvipc_proc_start(struct seq_file *s, loff_t *pos) |
778 | { | 800 | { |
@@ -807,7 +829,7 @@ static void sysvipc_proc_stop(struct seq_file *s, void *it) | |||
807 | struct ipc_proc_iface *iface = iter->iface; | 829 | struct ipc_proc_iface *iface = iter->iface; |
808 | struct ipc_ids *ids; | 830 | struct ipc_ids *ids; |
809 | 831 | ||
810 | /* If we had a locked segment, release it */ | 832 | /* If we had a locked structure, release it */ |
811 | if (ipc && ipc != SEQ_START_TOKEN) | 833 | if (ipc && ipc != SEQ_START_TOKEN) |
812 | ipc_unlock(ipc); | 834 | ipc_unlock(ipc); |
813 | 835 | ||
diff --git a/ipc/util.h b/ipc/util.h index 76f8a79902de..99414a36a250 100644 --- a/ipc/util.h +++ b/ipc/util.h | |||
@@ -54,7 +54,7 @@ struct ipc_params { | |||
54 | * the calls to sys_msgget(), sys_semget(), sys_shmget() | 54 | * the calls to sys_msgget(), sys_semget(), sys_shmget() |
55 | * . routine to call to create a new ipc object. Can be one of newque, | 55 | * . routine to call to create a new ipc object. Can be one of newque, |
56 | * newary, newseg | 56 | * newary, newseg |
57 | * . routine to call to call to check permissions for a new ipc object. | 57 | * . routine to call to check permissions for a new ipc object. |
58 | * Can be one of security_msg_associate, security_sem_associate, | 58 | * Can be one of security_msg_associate, security_sem_associate, |
59 | * security_shm_associate | 59 | * security_shm_associate |
60 | * . routine to call for an extra check if needed | 60 | * . routine to call for an extra check if needed |
@@ -88,7 +88,8 @@ int ipc_get_maxid(struct ipc_ids *); | |||
88 | /* must be called with both locks acquired. */ | 88 | /* must be called with both locks acquired. */ |
89 | void ipc_rmid(struct ipc_ids *, struct kern_ipc_perm *); | 89 | void ipc_rmid(struct ipc_ids *, struct kern_ipc_perm *); |
90 | 90 | ||
91 | int ipcperms (struct kern_ipc_perm *ipcp, short flg); | 91 | /* must be called with ipcp locked */ |
92 | int ipcperms(struct kern_ipc_perm *ipcp, short flg); | ||
92 | 93 | ||
93 | /* for rare, potentially huge allocations. | 94 | /* for rare, potentially huge allocations. |
94 | * both function can sleep | 95 | * both function can sleep |
@@ -131,6 +132,9 @@ static inline int ipc_buildid(struct ipc_ids *ids, int id, int seq) | |||
131 | return SEQ_MULTIPLIER * seq + id; | 132 | return SEQ_MULTIPLIER * seq + id; |
132 | } | 133 | } |
133 | 134 | ||
135 | /* | ||
136 | * Must be called with ipcp locked | ||
137 | */ | ||
134 | static inline int ipc_checkid(struct ipc_ids *ids, struct kern_ipc_perm *ipcp, | 138 | static inline int ipc_checkid(struct ipc_ids *ids, struct kern_ipc_perm *ipcp, |
135 | int uid) | 139 | int uid) |
136 | { | 140 | { |
@@ -168,6 +172,16 @@ static inline struct kern_ipc_perm *ipc_lock_check(struct ipc_ids *ids, | |||
168 | return out; | 172 | return out; |
169 | } | 173 | } |
170 | 174 | ||
175 | /** | ||
176 | * ipcget - Common sys_*get() code | ||
177 | * @ns : namsepace | ||
178 | * @ids : IPC identifier set | ||
179 | * @ops : operations to be called on ipc object creation, permission checks | ||
180 | * and further checks | ||
181 | * @params : the parameters needed by the previous operations. | ||
182 | * | ||
183 | * Common routine called by sys_msgget(), sys_semget() and sys_shmget(). | ||
184 | */ | ||
171 | static inline int ipcget(struct ipc_namespace *ns, struct ipc_ids *ids, | 185 | static inline int ipcget(struct ipc_namespace *ns, struct ipc_ids *ids, |
172 | struct ipc_ops *ops, struct ipc_params *params) | 186 | struct ipc_ops *ops, struct ipc_params *params) |
173 | { | 187 | { |