1// SPDX-License-Identifier: GPL-2.0 2/* 3 * linux/ipc/util.c 4 * Copyright (C) 1992 Krishna Balasubramanian 5 * 6 * Sep 1997 - Call suser() last after "normal" permission checks so we 7 * get BSD style process accounting right. 8 * Occurs in several places in the IPC code. 9 * Chris Evans, <chris@ferret.lmh.ox.ac.uk> 10 * Nov 1999 - ipc helper functions, unified SMP locking 11 * Manfred Spraul <manfred@colorfullife.com> 12 * Oct 2002 - One lock per IPC id. RCU ipc_free for lock-free grow_ary(). 13 * Mingming Cao <cmm@us.ibm.com> 14 * Mar 2006 - support for audit of ipc object properties 15 * Dustin Kirkland <dustin.kirkland@us.ibm.com> 16 * Jun 2006 - namespaces ssupport 17 * OpenVZ, SWsoft Inc. 18 * Pavel Emelianov <xemul@openvz.org> 19 * 20 * General sysv ipc locking scheme: 21 * rcu_read_lock() 22 * obtain the ipc object (kern_ipc_perm) by looking up the id in an idr 23 * tree. 24 * - perform initial checks (capabilities, auditing and permission, 25 * etc). 26 * - perform read-only operations, such as INFO command, that 27 * do not demand atomicity 28 * acquire the ipc lock (kern_ipc_perm.lock) through 29 * ipc_lock_object() 30 * - perform read-only operations that demand atomicity, 31 * such as STAT command. 32 * - perform data updates, such as SET, RMID commands and 33 * mechanism-specific operations (semop/semtimedop, 34 * msgsnd/msgrcv, shmat/shmdt). 35 * drop the ipc lock, through ipc_unlock_object(). 36 * rcu_read_unlock() 37 * 38 * The ids->rwsem must be taken when: 39 * - creating, removing and iterating the existing entries in ipc 40 * identifier sets. 41 * - iterating through files under /proc/sysvipc/ 42 * 43 * Note that sems have a special fast path that avoids kern_ipc_perm.lock - 44 * see sem_lock(). 45 */ 46 47#include <linux/mm.h> 48#include <linux/shm.h> 49#include <linux/init.h> 50#include <linux/msg.h> 51#include <linux/vmalloc.h> 52#include <linux/slab.h> 53#include <linux/notifier.h> 54#include <linux/capability.h> 55#include <linux/highuid.h> 56#include <linux/security.h> 57#include <linux/rcupdate.h> 58#include <linux/workqueue.h> 59#include <linux/seq_file.h> 60#include <linux/proc_fs.h> 61#include <linux/audit.h> 62#include <linux/nsproxy.h> 63#include <linux/rwsem.h> 64#include <linux/memory.h> 65#include <linux/ipc_namespace.h> 66#include <linux/rhashtable.h> 67 68#include <asm/unistd.h> 69 70#include "util.h" 71 72struct ipc_proc_iface { 73 const char *path; 74 const char *header; 75 int ids; 76 int (*show)(struct seq_file *, void *); 77}; 78 79/** 80 * ipc_init - initialise ipc subsystem 81 * 82 * The various sysv ipc resources (semaphores, messages and shared 83 * memory) are initialised. 84 * 85 * A callback routine is registered into the memory hotplug notifier 86 * chain: since msgmni scales to lowmem this callback routine will be 87 * called upon successful memory add / remove to recompute msmgni. 88 */ 89static int __init ipc_init(void) 90{ 91 proc_mkdir("sysvipc", NULL); 92 sem_init(); 93 msg_init(); 94 shm_init(); 95 96 return 0; 97} 98device_initcall(ipc_init); 99 100static const struct rhashtable_params ipc_kht_params = { 101 .head_offset = offsetof(struct kern_ipc_perm, khtnode), 102 .key_offset = offsetof(struct kern_ipc_perm, key), 103 .key_len = sizeof_field(struct kern_ipc_perm, key), 104 .automatic_shrinking = true, 105}; 106 107/** 108 * ipc_init_ids - initialise ipc identifiers 109 * @ids: ipc identifier set 110 * 111 * Set up the sequence range to use for the ipc identifier range (limited 112 * below ipc_mni) then initialise the keys hashtable and ids idr. 113 */ 114void ipc_init_ids(struct ipc_ids *ids) 115{ 116 ids->in_use = 0; 117 ids->seq = 0; 118 init_rwsem(&ids->rwsem); 119 rhashtable_init(&ids->key_ht, &ipc_kht_params); 120 idr_init(&ids->ipcs_idr); 121 ids->max_idx = -1; 122 ids->last_idx = -1; 123#ifdef CONFIG_CHECKPOINT_RESTORE 124 ids->next_id = -1; 125#endif 126} 127 128#ifdef CONFIG_PROC_FS 129static const struct proc_ops sysvipc_proc_ops; 130/** 131 * ipc_init_proc_interface - create a proc interface for sysipc types using a seq_file interface. 132 * @path: Path in procfs 133 * @header: Banner to be printed at the beginning of the file. 134 * @ids: ipc id table to iterate. 135 * @show: show routine. 136 */ 137void __init ipc_init_proc_interface(const char *path, const char *header, int ids, 138 int (*show)(struct seq_file *, void *)) 139{ 140 struct proc_dir_entry *pde; 141 struct ipc_proc_iface *iface; 142 143 iface = kmalloc(sizeof(*iface), GFP_KERNEL); 144 if (!iface) { 145 return; 146 } 147 iface->path = path; 148 iface->header = header; 149 iface->ids = ids; 150 iface->show = show; 151 152 pde = proc_create_data(path, S_IRUGO, /* world readable */ 153 NULL, /* parent dir */ 154 &sysvipc_proc_ops, iface); 155 if (!pde) { 156 kfree(iface); 157 } 158} 159#endif 160 161/** 162 * ipc_findkey - find a key in an ipc identifier set 163 * @ids: ipc identifier set 164 * @key: key to find 165 * 166 * Returns the locked pointer to the ipc structure if found or NULL 167 * otherwise. If key is found ipc points to the owning ipc structure 168 * 169 * Called with writer ipc_ids.rwsem held. 170 */ 171static struct kern_ipc_perm *ipc_findkey(struct ipc_ids *ids, key_t key) 172{ 173 struct kern_ipc_perm *ipcp; 174 175 ipcp = rhashtable_lookup_fast(&ids->key_ht, &key, ipc_kht_params); 176 if (!ipcp) { 177 return NULL; 178 } 179 180 rcu_read_lock(); 181 ipc_lock_object(ipcp); 182 return ipcp; 183} 184 185/* 186 * Insert new IPC object into idr tree, and set sequence number and id 187 * in the correct order. 188 * Especially: 189 * - the sequence number must be set before inserting the object into the idr, 190 * because the sequence number is accessed without a lock. 191 * - the id can/must be set after inserting the object into the idr. 192 * All accesses must be done after getting kern_ipc_perm.lock. 193 * 194 * The caller must own kern_ipc_perm.lock.of the new object. 195 * On error, the function returns a (negative) error code. 196 * 197 * To conserve sequence number space, especially with extended ipc_mni, 198 * the sequence number is incremented only when the returned ID is less than 199 * the last one. 200 */ 201static inline int ipc_idr_alloc(struct ipc_ids *ids, struct kern_ipc_perm *new) 202{ 203 int idx, next_id = -1; 204 205#ifdef CONFIG_CHECKPOINT_RESTORE 206 next_id = ids->next_id; 207 ids->next_id = -1; 208#endif 209 210 /* 211 * As soon as a new object is inserted into the idr, 212 * ipc_obtain_object_idr() or ipc_obtain_object_check() can find it, 213 * and the lockless preparations for ipc operations can start. 214 * This means especially: permission checks, audit calls, allocation 215 * of undo structures, ... 216 * 217 * Thus the object must be fully initialized, and if something fails, 218 * then the full tear-down sequence must be followed. 219 * (i.e.: set new->deleted, reduce refcount, call_rcu()) 220 */ 221 222 if (next_id < 0) { /* !CHECKPOINT_RESTORE or next_id is unset */ 223 int max_idx; 224 225 max_idx = max(ids->in_use * 0x3 / 0x2, ipc_min_cycle); 226 max_idx = min(max_idx, ipc_mni); 227 228 /* allocate the idx, with a NULL struct kern_ipc_perm */ 229 idx = idr_alloc_cyclic(&ids->ipcs_idr, NULL, 0, max_idx, GFP_NOWAIT); 230 if (idx >= 0) { 231 /* 232 * idx got allocated successfully. 233 * Now calculate the sequence number and set the 234 * pointer for real. 235 */ 236 if (idx <= ids->last_idx) { 237 ids->seq++; 238 if (ids->seq >= ipcid_seq_max()) { 239 ids->seq = 0; 240 } 241 } 242 ids->last_idx = idx; 243 244 new->seq = ids->seq; 245 /* no need for smp_wmb(), this is done 246 * inside idr_replace, as part of 247 * rcu_assign_pointer 248 */ 249 idr_replace(&ids->ipcs_idr, new, idx); 250 } 251 } else { 252 new->seq = ipcid_to_seqx(next_id); 253 idx = idr_alloc(&ids->ipcs_idr, new, ipcid_to_idx(next_id), 0, GFP_NOWAIT); 254 } 255 if (idx >= 0) { 256 new->id = (new->seq << ipcmni_seq_shift()) + idx; 257 } 258 return idx; 259} 260 261/** 262 * ipc_addid - add an ipc identifier 263 * @ids: ipc identifier set 264 * @new: new ipc permission set 265 * @limit: limit for the number of used ids 266 * 267 * Add an entry 'new' to the ipc ids idr. The permissions object is 268 * initialised and the first free entry is set up and the index assigned 269 * is returned. The 'new' entry is returned in a locked state on success. 270 * 271 * On failure the entry is not locked and a negative err-code is returned. 272 * The caller must use ipc_rcu_putref() to free the identifier. 273 * 274 * Called with writer ipc_ids.rwsem held. 275 */ 276int ipc_addid(struct ipc_ids *ids, struct kern_ipc_perm *new, int limit) 277{ 278 kuid_t euid; 279 kgid_t egid; 280 int idx, err; 281 282 /* 1) Initialize the refcount so that ipc_rcu_putref works */ 283 refcount_set(&new->refcount, 1); 284 285 if (limit > ipc_mni) { 286 limit = ipc_mni; 287 } 288 289 if (ids->in_use >= limit) { 290 return -ENOSPC; 291 } 292 293 idr_preload(GFP_KERNEL); 294 295 spin_lock_init(&new->lock); 296 rcu_read_lock(); 297 spin_lock(&new->lock); 298 299 current_euid_egid(&euid, &egid); 300 new->cuid = new->uid = euid; 301 new->gid = new->cgid = egid; 302 303 new->deleted = false; 304 305 idx = ipc_idr_alloc(ids, new); 306 idr_preload_end(); 307 308 if (idx >= 0 && new->key != IPC_PRIVATE) { 309 err = rhashtable_insert_fast(&ids->key_ht, &new->khtnode, ipc_kht_params); 310 if (err < 0) { 311 idr_remove(&ids->ipcs_idr, idx); 312 idx = err; 313 } 314 } 315 if (idx < 0) { 316 new->deleted = true; 317 spin_unlock(&new->lock); 318 rcu_read_unlock(); 319 return idx; 320 } 321 322 ids->in_use++; 323 if (idx > ids->max_idx) { 324 ids->max_idx = idx; 325 } 326 return idx; 327} 328 329/** 330 * ipcget_new - create a new ipc object 331 * @ns: ipc namespace 332 * @ids: ipc identifier set 333 * @ops: the actual creation routine to call 334 * @params: its parameters 335 * 336 * This routine is called by sys_msgget, sys_semget() and sys_shmget() 337 * when the key is IPC_PRIVATE. 338 */ 339static int ipcget_new(struct ipc_namespace *ns, struct ipc_ids *ids, const struct ipc_ops *ops, 340 struct ipc_params *params) 341{ 342 int err; 343 344 down_write(&ids->rwsem); 345 err = ops->getnew(ns, params); 346 up_write(&ids->rwsem); 347 return err; 348} 349 350/** 351 * ipc_check_perms - check security and permissions for an ipc object 352 * @ns: ipc namespace 353 * @ipcp: ipc permission set 354 * @ops: the actual security routine to call 355 * @params: its parameters 356 * 357 * This routine is called by sys_msgget(), sys_semget() and sys_shmget() 358 * when the key is not IPC_PRIVATE and that key already exists in the 359 * ds IDR. 360 * 361 * On success, the ipc id is returned. 362 * 363 * It is called with ipc_ids.rwsem and ipcp->lock held. 364 */ 365static int ipc_check_perms(struct ipc_namespace *ns, struct kern_ipc_perm *ipcp, const struct ipc_ops *ops, 366 struct ipc_params *params) 367{ 368 int err; 369 370 if (ipcperms(ns, ipcp, params->flg)) { 371 err = -EACCES; 372 } else { 373 err = ops->associate(ipcp, params->flg); 374 if (!err) { 375 err = ipcp->id; 376 } 377 } 378 379 return err; 380} 381 382/** 383 * ipcget_public - get an ipc object or create a new one 384 * @ns: ipc namespace 385 * @ids: ipc identifier set 386 * @ops: the actual creation routine to call 387 * @params: its parameters 388 * 389 * This routine is called by sys_msgget, sys_semget() and sys_shmget() 390 * when the key is not IPC_PRIVATE. 391 * It adds a new entry if the key is not found and does some permission 392 * / security checkings if the key is found. 393 * 394 * On success, the ipc id is returned. 395 */ 396static int ipcget_public(struct ipc_namespace *ns, struct ipc_ids *ids, const struct ipc_ops *ops, 397 struct ipc_params *params) 398{ 399 struct kern_ipc_perm *ipcp; 400 int flg = params->flg; 401 int err; 402 403 /* 404 * Take the lock as a writer since we are potentially going to add 405 * a new entry + read locks are not "upgradable" 406 */ 407 down_write(&ids->rwsem); 408 ipcp = ipc_findkey(ids, params->key); 409 if (ipcp == NULL) { 410 /* key not used */ 411 if (!(flg & IPC_CREAT)) { 412 err = -ENOENT; 413 } else { 414 err = ops->getnew(ns, params); 415 } 416 } else { 417 /* ipc object has been locked by ipc_findkey() */ 418 419 if ((flg & IPC_CREAT) && (flg & IPC_EXCL)) { 420 err = -EEXIST; 421 } else { 422 err = 0; 423 if (ops->more_checks) { 424 err = ops->more_checks(ipcp, params); 425 } 426 if (!err) { 427 /* 428 * ipc_check_perms returns the IPC id on 429 * success 430 */ 431 err = ipc_check_perms(ns, ipcp, ops, params); 432 } 433 } 434 ipc_unlock(ipcp); 435 } 436 up_write(&ids->rwsem); 437 438 return err; 439} 440 441/** 442 * ipc_kht_remove - remove an ipc from the key hashtable 443 * @ids: ipc identifier set 444 * @ipcp: ipc perm structure containing the key to remove 445 * 446 * ipc_ids.rwsem (as a writer) and the spinlock for this ID are held 447 * before this function is called, and remain locked on the exit. 448 */ 449static void ipc_kht_remove(struct ipc_ids *ids, struct kern_ipc_perm *ipcp) 450{ 451 if (ipcp->key != IPC_PRIVATE) { 452 WARN_ON_ONCE(rhashtable_remove_fast(&ids->key_ht, &ipcp->khtnode, ipc_kht_params)); 453 } 454} 455 456/** 457 * ipc_rmid - remove an ipc identifier 458 * @ids: ipc identifier set 459 * @ipcp: ipc perm structure containing the identifier to remove 460 * 461 * ipc_ids.rwsem (as a writer) and the spinlock for this ID are held 462 * before this function is called, and remain locked on the exit. 463 */ 464void ipc_rmid(struct ipc_ids *ids, struct kern_ipc_perm *ipcp) 465{ 466 int idx = ipcid_to_idx(ipcp->id); 467 468 WARN_ON_ONCE(idr_remove(&ids->ipcs_idr, idx) != ipcp); 469 ipc_kht_remove(ids, ipcp); 470 ids->in_use--; 471 ipcp->deleted = true; 472 473 if (unlikely(idx == ids->max_idx)) { 474 do { 475 idx--; 476 if (idx == -1) { 477 break; 478 } 479 } while (!idr_find(&ids->ipcs_idr, idx)); 480 ids->max_idx = idx; 481 } 482} 483 484/** 485 * ipc_set_key_private - switch the key of an existing ipc to IPC_PRIVATE 486 * @ids: ipc identifier set 487 * @ipcp: ipc perm structure containing the key to modify 488 * 489 * ipc_ids.rwsem (as a writer) and the spinlock for this ID are held 490 * before this function is called, and remain locked on the exit. 491 */ 492void ipc_set_key_private(struct ipc_ids *ids, struct kern_ipc_perm *ipcp) 493{ 494 ipc_kht_remove(ids, ipcp); 495 ipcp->key = IPC_PRIVATE; 496} 497 498bool ipc_rcu_getref(struct kern_ipc_perm *ptr) 499{ 500 return refcount_inc_not_zero(&ptr->refcount); 501} 502 503void ipc_rcu_putref(struct kern_ipc_perm *ptr, void (*func)(struct rcu_head *head)) 504{ 505 if (!refcount_dec_and_test(&ptr->refcount)) { 506 return; 507 } 508 509 call_rcu(&ptr->rcu, func); 510} 511 512/** 513 * ipcperms - check ipc permissions 514 * @ns: ipc namespace 515 * @ipcp: ipc permission set 516 * @flag: desired permission set 517 * 518 * Check user, group, other permissions for access 519 * to ipc resources. return 0 if allowed 520 * 521 * @flag will most probably be 0 or ``S_...UGO`` from <linux/stat.h> 522 */ 523int ipcperms(struct ipc_namespace *ns, struct kern_ipc_perm *ipcp, short flag) 524{ 525 kuid_t euid = current_euid(); 526 int requested_mode, granted_mode; 527 528 audit_ipc_obj(ipcp); 529 requested_mode = (flag >> 0x6) | (flag >> 0x3) | flag; 530 granted_mode = ipcp->mode; 531 if (uid_eq(euid, ipcp->cuid) || uid_eq(euid, ipcp->uid)) { 532 granted_mode >>= 0x6; 533 } else if (in_group_p(ipcp->cgid) || in_group_p(ipcp->gid)) { 534 granted_mode >>= 0x3; 535 } 536 /* is there some bit set in requested_mode but not in granted_mode? */ 537 if ((requested_mode & ~granted_mode & 0x7) && !ns_capable(ns->user_ns, CAP_IPC_OWNER)) { 538 return -1; 539 } 540 541 return security_ipc_permission(ipcp, flag); 542} 543 544/* 545 * Functions to convert between the kern_ipc_perm structure and the 546 * old/new ipc_perm structures 547 */ 548 549/** 550 * kernel_to_ipc64_perm - convert kernel ipc permissions to user 551 * @in: kernel permissions 552 * @out: new style ipc permissions 553 * 554 * Turn the kernel object @in into a set of permissions descriptions 555 * for returning to userspace (@out). 556 */ 557void kernel_to_ipc64_perm(struct kern_ipc_perm *in, struct ipc64_perm *out) 558{ 559 out->key = in->key; 560 out->uid = from_kuid_munged(current_user_ns(), in->uid); 561 out->gid = from_kgid_munged(current_user_ns(), in->gid); 562 out->cuid = from_kuid_munged(current_user_ns(), in->cuid); 563 out->cgid = from_kgid_munged(current_user_ns(), in->cgid); 564 out->mode = in->mode; 565 out->seq = in->seq; 566} 567 568/** 569 * ipc64_perm_to_ipc_perm - convert new ipc permissions to old 570 * @in: new style ipc permissions 571 * @out: old style ipc permissions 572 * 573 * Turn the new style permissions object @in into a compatibility 574 * object and store it into the @out pointer. 575 */ 576void ipc64_perm_to_ipc_perm(struct ipc64_perm *in, struct ipc_perm *out) 577{ 578 out->key = in->key; 579 SET_UID(out->uid, in->uid); 580 SET_GID(out->gid, in->gid); 581 SET_UID(out->cuid, in->cuid); 582 SET_GID(out->cgid, in->cgid); 583 out->mode = in->mode; 584 out->seq = in->seq; 585} 586 587/** 588 * ipc_obtain_object_idr 589 * @ids: ipc identifier set 590 * @id: ipc id to look for 591 * 592 * Look for an id in the ipc ids idr and return associated ipc object. 593 * 594 * Call inside the RCU critical section. 595 * The ipc object is *not* locked on exit. 596 */ 597struct kern_ipc_perm *ipc_obtain_object_idr(struct ipc_ids *ids, int id) 598{ 599 struct kern_ipc_perm *out; 600 int idx = ipcid_to_idx(id); 601 602 out = idr_find(&ids->ipcs_idr, idx); 603 if (!out) { 604 return ERR_PTR(-EINVAL); 605 } 606 607 return out; 608} 609 610/** 611 * ipc_obtain_object_check 612 * @ids: ipc identifier set 613 * @id: ipc id to look for 614 * 615 * Similar to ipc_obtain_object_idr() but also checks the ipc object 616 * sequence number. 617 * 618 * Call inside the RCU critical section. 619 * The ipc object is *not* locked on exit. 620 */ 621struct kern_ipc_perm *ipc_obtain_object_check(struct ipc_ids *ids, int id) 622{ 623 struct kern_ipc_perm *out = ipc_obtain_object_idr(ids, id); 624 625 if (IS_ERR(out)) { 626 goto out; 627 } 628 629 if (ipc_checkid(out, id)) { 630 return ERR_PTR(-EINVAL); 631 } 632out: 633 return out; 634} 635 636/** 637 * ipcget - Common sys_*get() code 638 * @ns: namespace 639 * @ids: ipc identifier set 640 * @ops: operations to be called on ipc object creation, permission checks 641 * and further checks 642 * @params: the parameters needed by the previous operations. 643 * 644 * Common routine called by sys_msgget(), sys_semget() and sys_shmget(). 645 */ 646int ipcget(struct ipc_namespace *ns, struct ipc_ids *ids, const struct ipc_ops *ops, struct ipc_params *params) 647{ 648 if (params->key == IPC_PRIVATE) { 649 return ipcget_new(ns, ids, ops, params); 650 } else { 651 return ipcget_public(ns, ids, ops, params); 652 } 653} 654 655/** 656 * ipc_update_perm - update the permissions of an ipc object 657 * @in: the permission given as input. 658 * @out: the permission of the ipc to set. 659 */ 660int ipc_update_perm(struct ipc64_perm *in, struct kern_ipc_perm *out) 661{ 662 kuid_t uid = make_kuid(current_user_ns(), in->uid); 663 kgid_t gid = make_kgid(current_user_ns(), in->gid); 664 if (!uid_valid(uid) || !gid_valid(gid)) { 665 return -EINVAL; 666 } 667 668 out->uid = uid; 669 out->gid = gid; 670 out->mode = (out->mode & ~S_IRWXUGO) | (in->mode & S_IRWXUGO); 671 672 return 0; 673} 674 675/** 676 * ipcctl_obtain_check - retrieve an ipc object and check permissions 677 * @ns: ipc namespace 678 * @ids: the table of ids where to look for the ipc 679 * @id: the id of the ipc to retrieve 680 * @cmd: the cmd to check 681 * @perm: the permission to set 682 * @extra_perm: one extra permission parameter used by msq 683 * 684 * This function does some common audit and permissions check for some IPC_XXX 685 * cmd and is called from semctl_down, shmctl_down and msgctl_down. 686 * 687 * It: 688 * - retrieves the ipc object with the given id in the given table. 689 * - performs some audit and permission check, depending on the given cmd 690 * - returns a pointer to the ipc object or otherwise, the corresponding 691 * error. 692 * 693 * Call holding the both the rwsem and the rcu read lock. 694 */ 695struct kern_ipc_perm *ipcctl_obtain_check(struct ipc_namespace *ns, struct ipc_ids *ids, int id, int cmd, 696 struct ipc64_perm *perm, int extra_perm) 697{ 698 kuid_t euid; 699 int err = -EPERM; 700 struct kern_ipc_perm *ipcp; 701 702 ipcp = ipc_obtain_object_check(ids, id); 703 if (IS_ERR(ipcp)) { 704 err = PTR_ERR(ipcp); 705 goto err; 706 } 707 708 audit_ipc_obj(ipcp); 709 if (cmd == IPC_SET) { 710 audit_ipc_set_perm(extra_perm, perm->uid, perm->gid, perm->mode); 711 } 712 713 euid = current_euid(); 714 if (uid_eq(euid, ipcp->cuid) || uid_eq(euid, ipcp->uid) || ns_capable(ns->user_ns, CAP_SYS_ADMIN)) { 715 return ipcp; /* successful lookup */ 716 } 717err: 718 return ERR_PTR(err); 719} 720 721#ifdef CONFIG_ARCH_WANT_IPC_PARSE_VERSION 722 723/** 724 * ipc_parse_version - ipc call version 725 * @cmd: pointer to command 726 * 727 * Return IPC_64 for new style IPC and IPC_OLD for old style IPC. 728 * The @cmd value is turned from an encoding command and version into 729 * just the command code. 730 */ 731int ipc_parse_version(int *cmd) 732{ 733 if (*cmd & IPC_64) { 734 *cmd ^= IPC_64; 735 return IPC_64; 736 } else { 737 return IPC_OLD; 738 } 739} 740 741#endif /* CONFIG_ARCH_WANT_IPC_PARSE_VERSION */ 742 743#ifdef CONFIG_PROC_FS 744struct ipc_proc_iter { 745 struct ipc_namespace *ns; 746 struct pid_namespace *pid_ns; 747 struct ipc_proc_iface *iface; 748}; 749 750struct pid_namespace *ipc_seq_pid_ns(struct seq_file *s) 751{ 752 struct ipc_proc_iter *iter = s->private; 753 return iter->pid_ns; 754} 755 756/* 757 * This routine locks the ipc structure found at least at position pos. 758 */ 759static struct kern_ipc_perm *sysvipc_find_ipc(struct ipc_ids *ids, loff_t pos, loff_t *new_pos) 760{ 761 struct kern_ipc_perm *ipc; 762 int total, id; 763 764 total = 0; 765 for (id = 0; id < pos && total < ids->in_use; id++) { 766 ipc = idr_find(&ids->ipcs_idr, id); 767 if (ipc != NULL) { 768 total++; 769 } 770 } 771 772 ipc = NULL; 773 if (total >= ids->in_use) { 774 goto out; 775 } 776 777 for (; pos < ipc_mni; pos++) { 778 ipc = idr_find(&ids->ipcs_idr, pos); 779 if (ipc != NULL) { 780 rcu_read_lock(); 781 ipc_lock_object(ipc); 782 break; 783 } 784 } 785out: 786 *new_pos = pos + 1; 787 return ipc; 788} 789 790static void *sysvipc_proc_next(struct seq_file *s, void *it, loff_t *pos) 791{ 792 struct ipc_proc_iter *iter = s->private; 793 struct ipc_proc_iface *iface = iter->iface; 794 struct kern_ipc_perm *ipc = it; 795 796 /* If we had an ipc id locked before, unlock it */ 797 if (ipc && ipc != SEQ_START_TOKEN) { 798 ipc_unlock(ipc); 799 } 800 801 return sysvipc_find_ipc(&iter->ns->ids[iface->ids], *pos, pos); 802} 803 804/* 805 * File positions: pos 0 -> header, pos n -> ipc id = n - 1. 806 * SeqFile iterator: iterator value locked ipc pointer or SEQ_TOKEN_START. 807 */ 808static void *sysvipc_proc_start(struct seq_file *s, loff_t *pos) 809{ 810 struct ipc_proc_iter *iter = s->private; 811 struct ipc_proc_iface *iface = iter->iface; 812 struct ipc_ids *ids; 813 814 ids = &iter->ns->ids[iface->ids]; 815 816 /* 817 * Take the lock - this will be released by the corresponding 818 * call to stop(). 819 */ 820 down_read(&ids->rwsem); 821 822 /* pos < 0 is invalid */ 823 if (*pos < 0) { 824 return NULL; 825 } 826 827 /* pos == 0 means header */ 828 if (*pos == 0) { 829 return SEQ_START_TOKEN; 830 } 831 832 /* Find the (pos-1)th ipc */ 833 return sysvipc_find_ipc(ids, *pos - 1, pos); 834} 835 836static void sysvipc_proc_stop(struct seq_file *s, void *it) 837{ 838 struct kern_ipc_perm *ipc = it; 839 struct ipc_proc_iter *iter = s->private; 840 struct ipc_proc_iface *iface = iter->iface; 841 struct ipc_ids *ids; 842 843 /* If we had a locked structure, release it */ 844 if (ipc && ipc != SEQ_START_TOKEN) { 845 ipc_unlock(ipc); 846 } 847 848 ids = &iter->ns->ids[iface->ids]; 849 /* Release the lock we took in start() */ 850 up_read(&ids->rwsem); 851} 852 853static int sysvipc_proc_show(struct seq_file *s, void *it) 854{ 855 struct ipc_proc_iter *iter = s->private; 856 struct ipc_proc_iface *iface = iter->iface; 857 858 if (it == SEQ_START_TOKEN) { 859 seq_puts(s, iface->header); 860 return 0; 861 } 862 863 return iface->show(s, it); 864} 865 866static const struct seq_operations sysvipc_proc_seqops = { 867 .start = sysvipc_proc_start, 868 .stop = sysvipc_proc_stop, 869 .next = sysvipc_proc_next, 870 .show = sysvipc_proc_show, 871}; 872 873static int sysvipc_proc_open(struct inode *inode, struct file *file) 874{ 875 struct ipc_proc_iter *iter; 876 877 iter = __seq_open_private(file, &sysvipc_proc_seqops, sizeof(*iter)); 878 if (!iter) { 879 return -ENOMEM; 880 } 881 882 iter->iface = PDE_DATA(inode); 883 iter->ns = get_ipc_ns(current->nsproxy->ipc_ns); 884 iter->pid_ns = get_pid_ns(task_active_pid_ns(current)); 885 886 return 0; 887} 888 889static int sysvipc_proc_release(struct inode *inode, struct file *file) 890{ 891 struct seq_file *seq = file->private_data; 892 struct ipc_proc_iter *iter = seq->private; 893 put_ipc_ns(iter->ns); 894 put_pid_ns(iter->pid_ns); 895 return seq_release_private(inode, file); 896} 897 898static const struct proc_ops sysvipc_proc_ops = { 899 .proc_flags = PROC_ENTRY_PERMANENT, 900 .proc_open = sysvipc_proc_open, 901 .proc_read = seq_read, 902 .proc_lseek = seq_lseek, 903 .proc_release = sysvipc_proc_release, 904}; 905#endif /* CONFIG_PROC_FS */ 906