Commit f4566f04854d78acfc74b9acb029744acde9d033

Authored by Nadia Derbey
Committed by Linus Torvalds
1 parent 2802831313

ipc: fix wrong comments

This patch fixes the wrong / obsolete comments in the ipc code.  Also adds
a missing lock around ipc_get_maxid() in shm_get_stat().

Signed-off-by: Nadia Derbey <Nadia.Derbey@bull.net>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

Showing 5 changed files with 118 additions and 45 deletions Side-by-side Diff

... ... @@ -156,6 +156,13 @@
156 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 166 static int newque(struct ipc_namespace *ns, struct ipc_params *params)
160 167 {
161 168 struct msg_queue *msq;
... ... @@ -250,8 +257,8 @@
250 257  
251 258 /*
252 259 * freeque() wakes up waiters on the sender and receiver waiting queue,
253   - * removes the message queue from message queue ID
254   - * IDR, and cleans up all the messages associated with this queue.
  260 + * removes the message queue from message queue ID IDR, and cleans up all the
  261 + * messages associated with this queue.
255 262 *
256 263 * msg_ids.mutex and the spinlock for this message queue are held
257 264 * before freeque() is called. msg_ids.mutex remains locked on exit.
... ... @@ -278,6 +285,9 @@
278 285 ipc_rcu_putref(msq);
279 286 }
280 287  
  288 +/*
  289 + * Called with msg_ids.mutex and ipcp locked.
  290 + */
281 291 static inline int msg_security(struct kern_ipc_perm *ipcp, int msgflg)
282 292 {
283 293 struct msg_queue *msq = container_of(ipcp, struct msg_queue, q_perm);
... ... @@ -228,6 +228,14 @@
228 228 */
229 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 239 static int newary(struct ipc_namespace *ns, struct ipc_params *params)
232 240 {
233 241 int id;
... ... @@ -281,6 +289,9 @@
281 289 }
282 290  
283 291  
  292 +/*
  293 + * Called with sem_ids.mutex and ipcp locked.
  294 + */
284 295 static inline int sem_security(struct kern_ipc_perm *ipcp, int semflg)
285 296 {
286 297 struct sem_array *sma;
... ... @@ -289,6 +300,9 @@
289 300 return security_sem_associate(sma, semflg);
290 301 }
291 302  
  303 +/*
  304 + * Called with sem_ids.mutex and ipcp locked.
  305 + */
292 306 static inline int sem_more_checks(struct kern_ipc_perm *ipcp,
293 307 struct ipc_params *params)
294 308 {
... ... @@ -82,6 +82,10 @@
82 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 89 static void do_shm_rmid(struct ipc_namespace *ns, struct shmid_kernel *shp)
86 90 {
87 91 if (shp->shm_nattch){
... ... @@ -182,6 +186,7 @@
182 186 /*
183 187 * shm_destroy - free the struct shmid_kernel
184 188 *
  189 + * @ns: namespace
185 190 * @shp: struct to free
186 191 *
187 192 * It has to be called with shp and shm_ids.mutex locked,
... ... @@ -343,6 +348,14 @@
343 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 359 static int newseg(struct ipc_namespace *ns, struct ipc_params *params)
347 360 {
348 361 key_t key = params->key;
... ... @@ -428,6 +441,9 @@
428 441 return error;
429 442 }
430 443  
  444 +/*
  445 + * Called with shm_ids.mutex and ipcp locked.
  446 + */
431 447 static inline int shm_security(struct kern_ipc_perm *ipcp, int shmflg)
432 448 {
433 449 struct shmid_kernel *shp;
... ... @@ -436,6 +452,9 @@
436 452 return security_shm_associate(shp, shmflg);
437 453 }
438 454  
  455 +/*
  456 + * Called with shm_ids.mutex and ipcp locked.
  457 + */
439 458 static inline int shm_more_checks(struct kern_ipc_perm *ipcp,
440 459 struct ipc_params *params)
441 460 {
... ... @@ -558,6 +577,9 @@
558 577 }
559 578 }
560 579  
  580 +/*
  581 + * Called with shm_ids.mutex held
  582 + */
561 583 static void shm_get_stat(struct ipc_namespace *ns, unsigned long *rss,
562 584 unsigned long *swp)
563 585 {
... ... @@ -573,18 +595,6 @@
573 595 struct shmid_kernel *shp;
574 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 598 shp = idr_find(&shm_ids(ns).ipcs_idr, next_id);
589 599 if (shp == NULL)
590 600 continue;
591 601  
... ... @@ -638,8 +648,11 @@
638 648 shminfo.shmmin = SHMMIN;
639 649 if(copy_shminfo_to_user (buf, &shminfo, version))
640 650 return -EFAULT;
641   - /* reading a integer is always atomic */
  651 +
  652 + mutex_lock(&shm_ids(ns).mutex);
642 653 err = ipc_get_maxid(&shm_ids(ns));
  654 + mutex_unlock(&shm_ids(ns).mutex);
  655 +
643 656 if(err<0)
644 657 err = 0;
645 658 goto out;
... ... @@ -194,7 +194,7 @@
194 194 * Requires ipc_ids.mutex locked.
195 195 * Returns the LOCKED pointer to the ipc structure if found or NULL
196 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 200 static struct kern_ipc_perm *ipc_findkey(struct ipc_ids *ids, key_t key)
201 201  
... ... @@ -258,10 +258,10 @@
258 258 * @new: new IPC permission set
259 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 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.
264   - * On failure the list is not locked and -1 is returned.
  263 + * is returned. The 'new' entry is returned in a locked state on success.
  264 + * On failure the entry is not locked and -1 is returned.
265 265 *
266 266 * Called with ipc_ids.mutex held.
267 267 */
... ... @@ -270,10 +270,6 @@
270 270 {
271 271 int id, err;
272 272  
273   - /*
274   - * rcu_dereference()() is not needed here since
275   - * ipc_ids.mutex is held
276   - */
277 273 if (size > IPCMNI)
278 274 size = IPCMNI;
279 275  
280 276  
... ... @@ -303,12 +299,12 @@
303 299 /**
304 300 * ipcget_new - create a new ipc object
305 301 * @ns: namespace
306   - * @ids: identifer set
  302 + * @ids: IPC identifer set
307 303 * @ops: the actual creation routine to call
308 304 * @params: its parameters
309 305 *
310   - * This routine is called sys_msgget, sys_semget() and sys_shmget() when
311   - * the key is IPC_PRIVATE
  306 + * This routine is called by sys_msgget, sys_semget() and sys_shmget()
  307 + * when the key is IPC_PRIVATE.
312 308 */
313 309 int ipcget_new(struct ipc_namespace *ns, struct ipc_ids *ids,
314 310 struct ipc_ops *ops, struct ipc_params *params)
315 311  
... ... @@ -330,9 +326,16 @@
330 326 /**
331 327 * ipc_check_perms - check security and permissions for an IPC
332 328 * @ipcp: ipc permission set
333   - * @ids: identifer set
334 329 * @ops: the actual security routine to call
335 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 340 static int ipc_check_perms(struct kern_ipc_perm *ipcp, struct ipc_ops *ops,
338 341 struct ipc_params *params)
339 342  
... ... @@ -353,12 +356,16 @@
353 356 /**
354 357 * ipcget_public - get an ipc object or create a new one
355 358 * @ns: namespace
356   - * @ids: identifer set
  359 + * @ids: IPC identifer set
357 360 * @ops: the actual creation routine to call
358 361 * @params: its parameters
359 362 *
360   - * This routine is called sys_msgget, sys_semget() and sys_shmget() when
361   - * the key is not IPC_PRIVATE
  363 + * This routine is called by sys_msgget, sys_semget() and sys_shmget()
  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 370 int ipcget_public(struct ipc_namespace *ns, struct ipc_ids *ids,
364 371 struct ipc_ops *ops, struct ipc_params *params)
... ... @@ -389,6 +396,10 @@
389 396 if (ops->more_checks)
390 397 err = ops->more_checks(ipcp, params);
391 398 if (!err)
  399 + /*
  400 + * ipc_check_perms returns the IPC id on
  401 + * success
  402 + */
392 403 err = ipc_check_perms(ipcp, ops, params);
393 404 }
394 405 ipc_unlock(ipcp);
395 406  
... ... @@ -401,12 +412,9 @@
401 412  
402 413 /**
403 414 * ipc_rmid - remove an IPC identifier
404   - * @ids: identifier set
405   - * @id: ipc perm structure containing the identifier to remove
  415 + * @ids: IPC identifier set
  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 418 * ipc_ids.mutex and the spinlock for this ID are held before this
411 419 * function is called, and remain locked on the exit.
412 420 */
413 421  
... ... @@ -558,11 +566,13 @@
558 566 */
559 567 static void ipc_schedule_free(struct rcu_head *head)
560 568 {
561   - struct ipc_rcu_grace *grace =
562   - container_of(head, struct ipc_rcu_grace, rcu);
563   - struct ipc_rcu_sched *sched =
564   - container_of(&(grace->data[0]), struct ipc_rcu_sched, data[0]);
  569 + struct ipc_rcu_grace *grace;
  570 + struct ipc_rcu_sched *sched;
565 571  
  572 + grace = container_of(head, struct ipc_rcu_grace, rcu);
  573 + sched = container_of(&(grace->data[0]), struct ipc_rcu_sched,
  574 + data[0]);
  575 +
566 576 INIT_WORK(&sched->work, ipc_do_vfree);
567 577 schedule_work(&sched->work);
568 578 }
... ... @@ -650,7 +660,7 @@
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 664 * @in: new style IPC permissions
655 665 * @out: old style IPC permissions
656 666 *
... ... @@ -669,6 +679,18 @@
669 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 694 struct kern_ipc_perm *ipc_lock(struct ipc_ids *ids, int id)
673 695 {
674 696 struct kern_ipc_perm *out;
... ... @@ -771,8 +793,8 @@
771 793 }
772 794  
773 795 /*
774   - * File positions: pos 0 -> header, pos n -> ipc id + 1.
775   - * SeqFile iterator: iterator value locked shp or SEQ_TOKEN_START.
  796 + * File positions: pos 0 -> header, pos n -> ipc id = n - 1.
  797 + * SeqFile iterator: iterator value locked ipc pointer or SEQ_TOKEN_START.
776 798 */
777 799 static void *sysvipc_proc_start(struct seq_file *s, loff_t *pos)
778 800 {
... ... @@ -807,7 +829,7 @@
807 829 struct ipc_proc_iface *iface = iter->iface;
808 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 833 if (ipc && ipc != SEQ_START_TOKEN)
812 834 ipc_unlock(ipc);
813 835  
... ... @@ -54,7 +54,7 @@
54 54 * the calls to sys_msgget(), sys_semget(), sys_shmget()
55 55 * . routine to call to create a new ipc object. Can be one of newque,
56 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 58 * Can be one of security_msg_associate, security_sem_associate,
59 59 * security_shm_associate
60 60 * . routine to call for an extra check if needed
... ... @@ -88,7 +88,8 @@
88 88 /* must be called with both locks acquired. */
89 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 94 /* for rare, potentially huge allocations.
94 95 * both function can sleep
... ... @@ -131,6 +132,9 @@
131 132 return SEQ_MULTIPLIER * seq + id;
132 133 }
133 134  
  135 +/*
  136 + * Must be called with ipcp locked
  137 + */
134 138 static inline int ipc_checkid(struct ipc_ids *ids, struct kern_ipc_perm *ipcp,
135 139 int uid)
136 140 {
... ... @@ -168,6 +172,16 @@
168 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 185 static inline int ipcget(struct ipc_namespace *ns, struct ipc_ids *ids,
172 186 struct ipc_ops *ops, struct ipc_params *params)
173 187 {