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 | { |
