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 72 struct 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 */ 89 static int __init ipc_init(void) 90 { 91 int err_sem, err_msg; 92 93 proc_mkdir("sysvipc", NULL); 94 err_sem = sem_init(); 95 WARN(err_sem, "ipc: sysv sem_init failed: %d\n", err_sem); 96 err_msg = msg_init(); 97 WARN(err_msg, "ipc: sysv msg_init failed: %d\n", err_msg); 98 shm_init(); 99 100 return err_msg ? err_msg : err_sem; 101 } 102 device_initcall(ipc_init); 103 104 static const struct rhashtable_params ipc_kht_params = { 105 .head_offset = offsetof(struct kern_ipc_perm, khtnode), 106 .key_offset = offsetof(struct kern_ipc_perm, key), 107 .key_len = FIELD_SIZEOF(struct kern_ipc_perm, key), 108 .locks_mul = 1, 109 .automatic_shrinking = true, 110 }; 111 112 /** 113 * ipc_init_ids - initialise ipc identifiers 114 * @ids: ipc identifier set 115 * 116 * Set up the sequence range to use for the ipc identifier range (limited 117 * below IPCMNI) then initialise the keys hashtable and ids idr. 118 */ 119 int ipc_init_ids(struct ipc_ids *ids) 120 { 121 int err; 122 ids->in_use = 0; 123 ids->seq = 0; 124 init_rwsem(&ids->rwsem); 125 err = rhashtable_init(&ids->key_ht, &ipc_kht_params); 126 if (err) 127 return err; 128 idr_init(&ids->ipcs_idr); 129 ids->tables_initialized = true; 130 ids->max_id = -1; 131 #ifdef CONFIG_CHECKPOINT_RESTORE 132 ids->next_id = -1; 133 #endif 134 return 0; 135 } 136 137 #ifdef CONFIG_PROC_FS 138 static const struct file_operations sysvipc_proc_fops; 139 /** 140 * ipc_init_proc_interface - create a proc interface for sysipc types using a seq_file interface. 141 * @path: Path in procfs 142 * @header: Banner to be printed at the beginning of the file. 143 * @ids: ipc id table to iterate. 144 * @show: show routine. 145 */ 146 void __init ipc_init_proc_interface(const char *path, const char *header, 147 int ids, int (*show)(struct seq_file *, void *)) 148 { 149 struct proc_dir_entry *pde; 150 struct ipc_proc_iface *iface; 151 152 iface = kmalloc(sizeof(*iface), GFP_KERNEL); 153 if (!iface) 154 return; 155 iface->path = path; 156 iface->header = header; 157 iface->ids = ids; 158 iface->show = show; 159 160 pde = proc_create_data(path, 161 S_IRUGO, /* world readable */ 162 NULL, /* parent dir */ 163 &sysvipc_proc_fops, 164 iface); 165 if (!pde) 166 kfree(iface); 167 } 168 #endif 169 170 /** 171 * ipc_findkey - find a key in an ipc identifier set 172 * @ids: ipc identifier set 173 * @key: key to find 174 * 175 * Returns the locked pointer to the ipc structure if found or NULL 176 * otherwise. If key is found ipc points to the owning ipc structure 177 * 178 * Called with writer ipc_ids.rwsem held. 179 */ 180 static struct kern_ipc_perm *ipc_findkey(struct ipc_ids *ids, key_t key) 181 { 182 struct kern_ipc_perm *ipcp = NULL; 183 184 if (likely(ids->tables_initialized)) 185 ipcp = rhashtable_lookup_fast(&ids->key_ht, &key, 186 ipc_kht_params); 187 188 if (ipcp) { 189 rcu_read_lock(); 190 ipc_lock_object(ipcp); 191 return ipcp; 192 } 193 194 return NULL; 195 } 196 197 /* 198 * Insert new IPC object into idr tree, and set sequence number and id 199 * in the correct order. 200 * Especially: 201 * - the sequence number must be set before inserting the object into the idr, 202 * because the sequence number is accessed without a lock. 203 * - the id can/must be set after inserting the object into the idr. 204 * All accesses must be done after getting kern_ipc_perm.lock. 205 * 206 * The caller must own kern_ipc_perm.lock.of the new object. 207 * On error, the function returns a (negative) error code. 208 */ 209 static inline int ipc_idr_alloc(struct ipc_ids *ids, struct kern_ipc_perm *new) 210 { 211 int idx, next_id = -1; 212 213 #ifdef CONFIG_CHECKPOINT_RESTORE 214 next_id = ids->next_id; 215 ids->next_id = -1; 216 #endif 217 218 /* 219 * As soon as a new object is inserted into the idr, 220 * ipc_obtain_object_idr() or ipc_obtain_object_check() can find it, 221 * and the lockless preparations for ipc operations can start. 222 * This means especially: permission checks, audit calls, allocation 223 * of undo structures, ... 224 * 225 * Thus the object must be fully initialized, and if something fails, 226 * then the full tear-down sequence must be followed. 227 * (i.e.: set new->deleted, reduce refcount, call_rcu()) 228 */ 229 230 if (next_id < 0) { /* !CHECKPOINT_RESTORE or next_id is unset */ 231 new->seq = ids->seq++; 232 if (ids->seq > IPCID_SEQ_MAX) 233 ids->seq = 0; 234 idx = idr_alloc(&ids->ipcs_idr, new, 0, 0, GFP_NOWAIT); 235 } else { 236 new->seq = ipcid_to_seqx(next_id); 237 idx = idr_alloc(&ids->ipcs_idr, new, ipcid_to_idx(next_id), 238 0, GFP_NOWAIT); 239 } 240 if (idx >= 0) 241 new->id = SEQ_MULTIPLIER * new->seq + idx; 242 return idx; 243 } 244 245 /** 246 * ipc_addid - add an ipc identifier 247 * @ids: ipc identifier set 248 * @new: new ipc permission set 249 * @limit: limit for the number of used ids 250 * 251 * Add an entry 'new' to the ipc ids idr. The permissions object is 252 * initialised and the first free entry is set up and the id assigned 253 * is returned. The 'new' entry is returned in a locked state on success. 254 * 255 * On failure the entry is not locked and a negative err-code is returned. 256 * The caller must use ipc_rcu_putref() to free the identifier. 257 * 258 * Called with writer ipc_ids.rwsem held. 259 */ 260 int ipc_addid(struct ipc_ids *ids, struct kern_ipc_perm *new, int limit) 261 { 262 kuid_t euid; 263 kgid_t egid; 264 int idx, err; 265 266 /* 1) Initialize the refcount so that ipc_rcu_putref works */ 267 refcount_set(&new->refcount, 1); 268 269 if (limit > IPCMNI) 270 limit = IPCMNI; 271 272 if (!ids->tables_initialized || ids->in_use >= limit) 273 return -ENOSPC; 274 275 idr_preload(GFP_KERNEL); 276 277 spin_lock_init(&new->lock); 278 rcu_read_lock(); 279 spin_lock(&new->lock); 280 281 current_euid_egid(&euid, &egid); 282 new->cuid = new->uid = euid; 283 new->gid = new->cgid = egid; 284 285 new->deleted = false; 286 287 idx = ipc_idr_alloc(ids, new); 288 idr_preload_end(); 289 290 if (idx >= 0 && new->key != IPC_PRIVATE) { 291 err = rhashtable_insert_fast(&ids->key_ht, &new->khtnode, 292 ipc_kht_params); 293 if (err < 0) { 294 idr_remove(&ids->ipcs_idr, idx); 295 idx = err; 296 } 297 } 298 if (idx < 0) { 299 new->deleted = true; 300 spin_unlock(&new->lock); 301 rcu_read_unlock(); 302 return idx; 303 } 304 305 ids->in_use++; 306 if (idx > ids->max_id) 307 ids->max_id = idx; 308 return idx; 309 } 310 311 /** 312 * ipcget_new - create a new ipc object 313 * @ns: ipc namespace 314 * @ids: ipc identifier set 315 * @ops: the actual creation routine to call 316 * @params: its parameters 317 * 318 * This routine is called by sys_msgget, sys_semget() and sys_shmget() 319 * when the key is IPC_PRIVATE. 320 */ 321 static int ipcget_new(struct ipc_namespace *ns, struct ipc_ids *ids, 322 const struct ipc_ops *ops, struct ipc_params *params) 323 { 324 int err; 325 326 down_write(&ids->rwsem); 327 err = ops->getnew(ns, params); 328 up_write(&ids->rwsem); 329 return err; 330 } 331 332 /** 333 * ipc_check_perms - check security and permissions for an ipc object 334 * @ns: ipc namespace 335 * @ipcp: ipc permission set 336 * @ops: the actual security routine to call 337 * @params: its parameters 338 * 339 * This routine is called by sys_msgget(), sys_semget() and sys_shmget() 340 * when the key is not IPC_PRIVATE and that key already exists in the 341 * ds IDR. 342 * 343 * On success, the ipc id is returned. 344 * 345 * It is called with ipc_ids.rwsem and ipcp->lock held. 346 */ 347 static int ipc_check_perms(struct ipc_namespace *ns, 348 struct kern_ipc_perm *ipcp, 349 const struct ipc_ops *ops, 350 struct ipc_params *params) 351 { 352 int err; 353 354 if (ipcperms(ns, ipcp, params->flg)) 355 err = -EACCES; 356 else { 357 err = ops->associate(ipcp, params->flg); 358 if (!err) 359 err = ipcp->id; 360 } 361 362 return err; 363 } 364 365 /** 366 * ipcget_public - get an ipc object or create a new one 367 * @ns: ipc namespace 368 * @ids: ipc identifier set 369 * @ops: the actual creation routine to call 370 * @params: its parameters 371 * 372 * This routine is called by sys_msgget, sys_semget() and sys_shmget() 373 * when the key is not IPC_PRIVATE. 374 * It adds a new entry if the key is not found and does some permission 375 * / security checkings if the key is found. 376 * 377 * On success, the ipc id is returned. 378 */ 379 static int ipcget_public(struct ipc_namespace *ns, struct ipc_ids *ids, 380 const struct ipc_ops *ops, struct ipc_params *params) 381 { 382 struct kern_ipc_perm *ipcp; 383 int flg = params->flg; 384 int err; 385 386 /* 387 * Take the lock as a writer since we are potentially going to add 388 * a new entry + read locks are not "upgradable" 389 */ 390 down_write(&ids->rwsem); 391 ipcp = ipc_findkey(ids, params->key); 392 if (ipcp == NULL) { 393 /* key not used */ 394 if (!(flg & IPC_CREAT)) 395 err = -ENOENT; 396 else 397 err = ops->getnew(ns, params); 398 } else { 399 /* ipc object has been locked by ipc_findkey() */ 400 401 if (flg & IPC_CREAT && flg & IPC_EXCL) 402 err = -EEXIST; 403 else { 404 err = 0; 405 if (ops->more_checks) 406 err = ops->more_checks(ipcp, params); 407 if (!err) 408 /* 409 * ipc_check_perms returns the IPC id on 410 * success 411 */ 412 err = ipc_check_perms(ns, ipcp, ops, params); 413 } 414 ipc_unlock(ipcp); 415 } 416 up_write(&ids->rwsem); 417 418 return err; 419 } 420 421 /** 422 * ipc_kht_remove - remove an ipc from the key hashtable 423 * @ids: ipc identifier set 424 * @ipcp: ipc perm structure containing the key to remove 425 * 426 * ipc_ids.rwsem (as a writer) and the spinlock for this ID are held 427 * before this function is called, and remain locked on the exit. 428 */ 429 static void ipc_kht_remove(struct ipc_ids *ids, struct kern_ipc_perm *ipcp) 430 { 431 if (ipcp->key != IPC_PRIVATE) 432 rhashtable_remove_fast(&ids->key_ht, &ipcp->khtnode, 433 ipc_kht_params); 434 } 435 436 /** 437 * ipc_rmid - remove an ipc identifier 438 * @ids: ipc identifier set 439 * @ipcp: ipc perm structure containing the identifier to remove 440 * 441 * ipc_ids.rwsem (as a writer) and the spinlock for this ID are held 442 * before this function is called, and remain locked on the exit. 443 */ 444 void ipc_rmid(struct ipc_ids *ids, struct kern_ipc_perm *ipcp) 445 { 446 int lid = ipcid_to_idx(ipcp->id); 447 448 idr_remove(&ids->ipcs_idr, lid); 449 ipc_kht_remove(ids, ipcp); 450 ids->in_use--; 451 ipcp->deleted = true; 452 453 if (unlikely(lid == ids->max_id)) { 454 do { 455 lid--; 456 if (lid == -1) 457 break; 458 } while (!idr_find(&ids->ipcs_idr, lid)); 459 ids->max_id = lid; 460 } 461 } 462 463 /** 464 * ipc_set_key_private - switch the key of an existing ipc to IPC_PRIVATE 465 * @ids: ipc identifier set 466 * @ipcp: ipc perm structure containing the key to modify 467 * 468 * ipc_ids.rwsem (as a writer) and the spinlock for this ID are held 469 * before this function is called, and remain locked on the exit. 470 */ 471 void ipc_set_key_private(struct ipc_ids *ids, struct kern_ipc_perm *ipcp) 472 { 473 ipc_kht_remove(ids, ipcp); 474 ipcp->key = IPC_PRIVATE; 475 } 476 477 int ipc_rcu_getref(struct kern_ipc_perm *ptr) 478 { 479 return refcount_inc_not_zero(&ptr->refcount); 480 } 481 482 void ipc_rcu_putref(struct kern_ipc_perm *ptr, 483 void (*func)(struct rcu_head *head)) 484 { 485 if (!refcount_dec_and_test(&ptr->refcount)) 486 return; 487 488 call_rcu(&ptr->rcu, func); 489 } 490 491 /** 492 * ipcperms - check ipc permissions 493 * @ns: ipc namespace 494 * @ipcp: ipc permission set 495 * @flag: desired permission set 496 * 497 * Check user, group, other permissions for access 498 * to ipc resources. return 0 if allowed 499 * 500 * @flag will most probably be 0 or ``S_...UGO`` from <linux/stat.h> 501 */ 502 int ipcperms(struct ipc_namespace *ns, struct kern_ipc_perm *ipcp, short flag) 503 { 504 kuid_t euid = current_euid(); 505 int requested_mode, granted_mode; 506 507 audit_ipc_obj(ipcp); 508 requested_mode = (flag >> 6) | (flag >> 3) | flag; 509 granted_mode = ipcp->mode; 510 if (uid_eq(euid, ipcp->cuid) || 511 uid_eq(euid, ipcp->uid)) 512 granted_mode >>= 6; 513 else if (in_group_p(ipcp->cgid) || in_group_p(ipcp->gid)) 514 granted_mode >>= 3; 515 /* is there some bit set in requested_mode but not in granted_mode? */ 516 if ((requested_mode & ~granted_mode & 0007) && 517 !ns_capable(ns->user_ns, CAP_IPC_OWNER)) 518 return -1; 519 520 return security_ipc_permission(ipcp, flag); 521 } 522 523 /* 524 * Functions to convert between the kern_ipc_perm structure and the 525 * old/new ipc_perm structures 526 */ 527 528 /** 529 * kernel_to_ipc64_perm - convert kernel ipc permissions to user 530 * @in: kernel permissions 531 * @out: new style ipc permissions 532 * 533 * Turn the kernel object @in into a set of permissions descriptions 534 * for returning to userspace (@out). 535 */ 536 void kernel_to_ipc64_perm(struct kern_ipc_perm *in, struct ipc64_perm *out) 537 { 538 out->key = in->key; 539 out->uid = from_kuid_munged(current_user_ns(), in->uid); 540 out->gid = from_kgid_munged(current_user_ns(), in->gid); 541 out->cuid = from_kuid_munged(current_user_ns(), in->cuid); 542 out->cgid = from_kgid_munged(current_user_ns(), in->cgid); 543 out->mode = in->mode; 544 out->seq = in->seq; 545 } 546 547 /** 548 * ipc64_perm_to_ipc_perm - convert new ipc permissions to old 549 * @in: new style ipc permissions 550 * @out: old style ipc permissions 551 * 552 * Turn the new style permissions object @in into a compatibility 553 * object and store it into the @out pointer. 554 */ 555 void ipc64_perm_to_ipc_perm(struct ipc64_perm *in, struct ipc_perm *out) 556 { 557 out->key = in->key; 558 SET_UID(out->uid, in->uid); 559 SET_GID(out->gid, in->gid); 560 SET_UID(out->cuid, in->cuid); 561 SET_GID(out->cgid, in->cgid); 562 out->mode = in->mode; 563 out->seq = in->seq; 564 } 565 566 /** 567 * ipc_obtain_object_idr 568 * @ids: ipc identifier set 569 * @id: ipc id to look for 570 * 571 * Look for an id in the ipc ids idr and return associated ipc object. 572 * 573 * Call inside the RCU critical section. 574 * The ipc object is *not* locked on exit. 575 */ 576 struct kern_ipc_perm *ipc_obtain_object_idr(struct ipc_ids *ids, int id) 577 { 578 struct kern_ipc_perm *out; 579 int lid = ipcid_to_idx(id); 580 581 if (unlikely(!ids->tables_initialized)) 582 return ERR_PTR(-EINVAL); 583 584 out = idr_find(&ids->ipcs_idr, lid); 585 if (!out) 586 return ERR_PTR(-EINVAL); 587 588 return out; 589 } 590 591 /** 592 * ipc_obtain_object_check 593 * @ids: ipc identifier set 594 * @id: ipc id to look for 595 * 596 * Similar to ipc_obtain_object_idr() but also checks the ipc object 597 * sequence number. 598 * 599 * Call inside the RCU critical section. 600 * The ipc object is *not* locked on exit. 601 */ 602 struct kern_ipc_perm *ipc_obtain_object_check(struct ipc_ids *ids, int id) 603 { 604 struct kern_ipc_perm *out = ipc_obtain_object_idr(ids, id); 605 606 if (IS_ERR(out)) 607 goto out; 608 609 if (ipc_checkid(out, id)) 610 return ERR_PTR(-EINVAL); 611 out: 612 return out; 613 } 614 615 /** 616 * ipcget - Common sys_*get() code 617 * @ns: namespace 618 * @ids: ipc identifier set 619 * @ops: operations to be called on ipc object creation, permission checks 620 * and further checks 621 * @params: the parameters needed by the previous operations. 622 * 623 * Common routine called by sys_msgget(), sys_semget() and sys_shmget(). 624 */ 625 int ipcget(struct ipc_namespace *ns, struct ipc_ids *ids, 626 const struct ipc_ops *ops, struct ipc_params *params) 627 { 628 if (params->key == IPC_PRIVATE) 629 return ipcget_new(ns, ids, ops, params); 630 else 631 return ipcget_public(ns, ids, ops, params); 632 } 633 634 /** 635 * ipc_update_perm - update the permissions of an ipc object 636 * @in: the permission given as input. 637 * @out: the permission of the ipc to set. 638 */ 639 int ipc_update_perm(struct ipc64_perm *in, struct kern_ipc_perm *out) 640 { 641 kuid_t uid = make_kuid(current_user_ns(), in->uid); 642 kgid_t gid = make_kgid(current_user_ns(), in->gid); 643 if (!uid_valid(uid) || !gid_valid(gid)) 644 return -EINVAL; 645 646 out->uid = uid; 647 out->gid = gid; 648 out->mode = (out->mode & ~S_IRWXUGO) 649 | (in->mode & S_IRWXUGO); 650 651 return 0; 652 } 653 654 /** 655 * ipcctl_obtain_check - retrieve an ipc object and check permissions 656 * @ns: ipc namespace 657 * @ids: the table of ids where to look for the ipc 658 * @id: the id of the ipc to retrieve 659 * @cmd: the cmd to check 660 * @perm: the permission to set 661 * @extra_perm: one extra permission parameter used by msq 662 * 663 * This function does some common audit and permissions check for some IPC_XXX 664 * cmd and is called from semctl_down, shmctl_down and msgctl_down. 665 * 666 * It: 667 * - retrieves the ipc object with the given id in the given table. 668 * - performs some audit and permission check, depending on the given cmd 669 * - returns a pointer to the ipc object or otherwise, the corresponding 670 * error. 671 * 672 * Call holding the both the rwsem and the rcu read lock. 673 */ 674 struct kern_ipc_perm *ipcctl_obtain_check(struct ipc_namespace *ns, 675 struct ipc_ids *ids, int id, int cmd, 676 struct ipc64_perm *perm, int extra_perm) 677 { 678 kuid_t euid; 679 int err = -EPERM; 680 struct kern_ipc_perm *ipcp; 681 682 ipcp = ipc_obtain_object_check(ids, id); 683 if (IS_ERR(ipcp)) { 684 err = PTR_ERR(ipcp); 685 goto err; 686 } 687 688 audit_ipc_obj(ipcp); 689 if (cmd == IPC_SET) 690 audit_ipc_set_perm(extra_perm, perm->uid, 691 perm->gid, perm->mode); 692 693 euid = current_euid(); 694 if (uid_eq(euid, ipcp->cuid) || uid_eq(euid, ipcp->uid) || 695 ns_capable(ns->user_ns, CAP_SYS_ADMIN)) 696 return ipcp; /* successful lookup */ 697 err: 698 return ERR_PTR(err); 699 } 700 701 #ifdef CONFIG_ARCH_WANT_IPC_PARSE_VERSION 702 703 704 /** 705 * ipc_parse_version - ipc call version 706 * @cmd: pointer to command 707 * 708 * Return IPC_64 for new style IPC and IPC_OLD for old style IPC. 709 * The @cmd value is turned from an encoding command and version into 710 * just the command code. 711 */ 712 int ipc_parse_version(int *cmd) 713 { 714 if (*cmd & IPC_64) { 715 *cmd ^= IPC_64; 716 return IPC_64; 717 } else { 718 return IPC_OLD; 719 } 720 } 721 722 #endif /* CONFIG_ARCH_WANT_IPC_PARSE_VERSION */ 723 724 #ifdef CONFIG_PROC_FS 725 struct ipc_proc_iter { 726 struct ipc_namespace *ns; 727 struct pid_namespace *pid_ns; 728 struct ipc_proc_iface *iface; 729 }; 730 731 struct pid_namespace *ipc_seq_pid_ns(struct seq_file *s) 732 { 733 struct ipc_proc_iter *iter = s->private; 734 return iter->pid_ns; 735 } 736 737 /* 738 * This routine locks the ipc structure found at least at position pos. 739 */ 740 static struct kern_ipc_perm *sysvipc_find_ipc(struct ipc_ids *ids, loff_t pos, 741 loff_t *new_pos) 742 { 743 struct kern_ipc_perm *ipc; 744 int total, id; 745 746 total = 0; 747 for (id = 0; id < pos && total < ids->in_use; id++) { 748 ipc = idr_find(&ids->ipcs_idr, id); 749 if (ipc != NULL) 750 total++; 751 } 752 753 if (total >= ids->in_use) 754 return NULL; 755 756 for (; pos < IPCMNI; pos++) { 757 ipc = idr_find(&ids->ipcs_idr, pos); 758 if (ipc != NULL) { 759 *new_pos = pos + 1; 760 rcu_read_lock(); 761 ipc_lock_object(ipc); 762 return ipc; 763 } 764 } 765 766 /* Out of range - return NULL to terminate iteration */ 767 return NULL; 768 } 769 770 static void *sysvipc_proc_next(struct seq_file *s, void *it, loff_t *pos) 771 { 772 struct ipc_proc_iter *iter = s->private; 773 struct ipc_proc_iface *iface = iter->iface; 774 struct kern_ipc_perm *ipc = it; 775 776 /* If we had an ipc id locked before, unlock it */ 777 if (ipc && ipc != SEQ_START_TOKEN) 778 ipc_unlock(ipc); 779 780 return sysvipc_find_ipc(&iter->ns->ids[iface->ids], *pos, pos); 781 } 782 783 /* 784 * File positions: pos 0 -> header, pos n -> ipc id = n - 1. 785 * SeqFile iterator: iterator value locked ipc pointer or SEQ_TOKEN_START. 786 */ 787 static void *sysvipc_proc_start(struct seq_file *s, loff_t *pos) 788 { 789 struct ipc_proc_iter *iter = s->private; 790 struct ipc_proc_iface *iface = iter->iface; 791 struct ipc_ids *ids; 792 793 ids = &iter->ns->ids[iface->ids]; 794 795 /* 796 * Take the lock - this will be released by the corresponding 797 * call to stop(). 798 */ 799 down_read(&ids->rwsem); 800 801 /* pos < 0 is invalid */ 802 if (*pos < 0) 803 return NULL; 804 805 /* pos == 0 means header */ 806 if (*pos == 0) 807 return SEQ_START_TOKEN; 808 809 /* Find the (pos-1)th ipc */ 810 return sysvipc_find_ipc(ids, *pos - 1, pos); 811 } 812 813 static void sysvipc_proc_stop(struct seq_file *s, void *it) 814 { 815 struct kern_ipc_perm *ipc = it; 816 struct ipc_proc_iter *iter = s->private; 817 struct ipc_proc_iface *iface = iter->iface; 818 struct ipc_ids *ids; 819 820 /* If we had a locked structure, release it */ 821 if (ipc && ipc != SEQ_START_TOKEN) 822 ipc_unlock(ipc); 823 824 ids = &iter->ns->ids[iface->ids]; 825 /* Release the lock we took in start() */ 826 up_read(&ids->rwsem); 827 } 828 829 static int sysvipc_proc_show(struct seq_file *s, void *it) 830 { 831 struct ipc_proc_iter *iter = s->private; 832 struct ipc_proc_iface *iface = iter->iface; 833 834 if (it == SEQ_START_TOKEN) { 835 seq_puts(s, iface->header); 836 return 0; 837 } 838 839 return iface->show(s, it); 840 } 841 842 static const struct seq_operations sysvipc_proc_seqops = { 843 .start = sysvipc_proc_start, 844 .stop = sysvipc_proc_stop, 845 .next = sysvipc_proc_next, 846 .show = sysvipc_proc_show, 847 }; 848 849 static int sysvipc_proc_open(struct inode *inode, struct file *file) 850 { 851 struct ipc_proc_iter *iter; 852 853 iter = __seq_open_private(file, &sysvipc_proc_seqops, sizeof(*iter)); 854 if (!iter) 855 return -ENOMEM; 856 857 iter->iface = PDE_DATA(inode); 858 iter->ns = get_ipc_ns(current->nsproxy->ipc_ns); 859 iter->pid_ns = get_pid_ns(task_active_pid_ns(current)); 860 861 return 0; 862 } 863 864 static int sysvipc_proc_release(struct inode *inode, struct file *file) 865 { 866 struct seq_file *seq = file->private_data; 867 struct ipc_proc_iter *iter = seq->private; 868 put_ipc_ns(iter->ns); 869 put_pid_ns(iter->pid_ns); 870 return seq_release_private(inode, file); 871 } 872 873 static const struct file_operations sysvipc_proc_fops = { 874 .open = sysvipc_proc_open, 875 .read = seq_read, 876 .llseek = seq_lseek, 877 .release = sysvipc_proc_release, 878 }; 879 #endif /* CONFIG_PROC_FS */ 880