Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  * linux/ipc/util.c
0004  * Copyright (C) 1992 Krishna Balasubramanian
0005  *
0006  * Sep 1997 - Call suser() last after "normal" permission checks so we
0007  *            get BSD style process accounting right.
0008  *            Occurs in several places in the IPC code.
0009  *            Chris Evans, <chris@ferret.lmh.ox.ac.uk>
0010  * Nov 1999 - ipc helper functions, unified SMP locking
0011  *        Manfred Spraul <manfred@colorfullife.com>
0012  * Oct 2002 - One lock per IPC id. RCU ipc_free for lock-free grow_ary().
0013  *            Mingming Cao <cmm@us.ibm.com>
0014  * Mar 2006 - support for audit of ipc object properties
0015  *            Dustin Kirkland <dustin.kirkland@us.ibm.com>
0016  * Jun 2006 - namespaces ssupport
0017  *            OpenVZ, SWsoft Inc.
0018  *            Pavel Emelianov <xemul@openvz.org>
0019  *
0020  * General sysv ipc locking scheme:
0021  *  rcu_read_lock()
0022  *          obtain the ipc object (kern_ipc_perm) by looking up the id in an idr
0023  *      tree.
0024  *      - perform initial checks (capabilities, auditing and permission,
0025  *        etc).
0026  *      - perform read-only operations, such as INFO command, that
0027  *        do not demand atomicity
0028  *        acquire the ipc lock (kern_ipc_perm.lock) through
0029  *        ipc_lock_object()
0030  *      - perform read-only operations that demand atomicity,
0031  *        such as STAT command.
0032  *      - perform data updates, such as SET, RMID commands and
0033  *        mechanism-specific operations (semop/semtimedop,
0034  *        msgsnd/msgrcv, shmat/shmdt).
0035  *      drop the ipc lock, through ipc_unlock_object().
0036  *  rcu_read_unlock()
0037  *
0038  *  The ids->rwsem must be taken when:
0039  *  - creating, removing and iterating the existing entries in ipc
0040  *    identifier sets.
0041  *  - iterating through files under /proc/sysvipc/
0042  *
0043  *  Note that sems have a special fast path that avoids kern_ipc_perm.lock -
0044  *  see sem_lock().
0045  */
0046 
0047 #include <linux/mm.h>
0048 #include <linux/shm.h>
0049 #include <linux/init.h>
0050 #include <linux/msg.h>
0051 #include <linux/vmalloc.h>
0052 #include <linux/slab.h>
0053 #include <linux/notifier.h>
0054 #include <linux/capability.h>
0055 #include <linux/highuid.h>
0056 #include <linux/security.h>
0057 #include <linux/rcupdate.h>
0058 #include <linux/workqueue.h>
0059 #include <linux/seq_file.h>
0060 #include <linux/proc_fs.h>
0061 #include <linux/audit.h>
0062 #include <linux/nsproxy.h>
0063 #include <linux/rwsem.h>
0064 #include <linux/memory.h>
0065 #include <linux/ipc_namespace.h>
0066 #include <linux/rhashtable.h>
0067 #include <linux/log2.h>
0068 
0069 #include <asm/unistd.h>
0070 
0071 #include "util.h"
0072 
0073 struct ipc_proc_iface {
0074     const char *path;
0075     const char *header;
0076     int ids;
0077     int (*show)(struct seq_file *, void *);
0078 };
0079 
0080 /**
0081  * ipc_init - initialise ipc subsystem
0082  *
0083  * The various sysv ipc resources (semaphores, messages and shared
0084  * memory) are initialised.
0085  *
0086  * A callback routine is registered into the memory hotplug notifier
0087  * chain: since msgmni scales to lowmem this callback routine will be
0088  * called upon successful memory add / remove to recompute msmgni.
0089  */
0090 static int __init ipc_init(void)
0091 {
0092     proc_mkdir("sysvipc", NULL);
0093     sem_init();
0094     msg_init();
0095     shm_init();
0096 
0097     return 0;
0098 }
0099 device_initcall(ipc_init);
0100 
0101 static const struct rhashtable_params ipc_kht_params = {
0102     .head_offset        = offsetof(struct kern_ipc_perm, khtnode),
0103     .key_offset     = offsetof(struct kern_ipc_perm, key),
0104     .key_len        = sizeof_field(struct kern_ipc_perm, key),
0105     .automatic_shrinking    = true,
0106 };
0107 
0108 /**
0109  * ipc_init_ids - initialise ipc identifiers
0110  * @ids: ipc identifier set
0111  *
0112  * Set up the sequence range to use for the ipc identifier range (limited
0113  * below ipc_mni) then initialise the keys hashtable and ids idr.
0114  */
0115 void ipc_init_ids(struct ipc_ids *ids)
0116 {
0117     ids->in_use = 0;
0118     ids->seq = 0;
0119     init_rwsem(&ids->rwsem);
0120     rhashtable_init(&ids->key_ht, &ipc_kht_params);
0121     idr_init(&ids->ipcs_idr);
0122     ids->max_idx = -1;
0123     ids->last_idx = -1;
0124 #ifdef CONFIG_CHECKPOINT_RESTORE
0125     ids->next_id = -1;
0126 #endif
0127 }
0128 
0129 #ifdef CONFIG_PROC_FS
0130 static const struct proc_ops sysvipc_proc_ops;
0131 /**
0132  * ipc_init_proc_interface -  create a proc interface for sysipc types using a seq_file interface.
0133  * @path: Path in procfs
0134  * @header: Banner to be printed at the beginning of the file.
0135  * @ids: ipc id table to iterate.
0136  * @show: show routine.
0137  */
0138 void __init ipc_init_proc_interface(const char *path, const char *header,
0139         int ids, int (*show)(struct seq_file *, void *))
0140 {
0141     struct proc_dir_entry *pde;
0142     struct ipc_proc_iface *iface;
0143 
0144     iface = kmalloc(sizeof(*iface), GFP_KERNEL);
0145     if (!iface)
0146         return;
0147     iface->path = path;
0148     iface->header   = header;
0149     iface->ids  = ids;
0150     iface->show = show;
0151 
0152     pde = proc_create_data(path,
0153                    S_IRUGO,        /* world readable */
0154                    NULL,           /* parent dir */
0155                    &sysvipc_proc_ops,
0156                    iface);
0157     if (!pde)
0158         kfree(iface);
0159 }
0160 #endif
0161 
0162 /**
0163  * ipc_findkey  - find a key in an ipc identifier set
0164  * @ids: ipc identifier set
0165  * @key: key to find
0166  *
0167  * Returns the locked pointer to the ipc structure if found or NULL
0168  * otherwise. If key is found ipc points to the owning ipc structure
0169  *
0170  * Called with writer ipc_ids.rwsem held.
0171  */
0172 static struct kern_ipc_perm *ipc_findkey(struct ipc_ids *ids, key_t key)
0173 {
0174     struct kern_ipc_perm *ipcp;
0175 
0176     ipcp = rhashtable_lookup_fast(&ids->key_ht, &key,
0177                           ipc_kht_params);
0178     if (!ipcp)
0179         return NULL;
0180 
0181     rcu_read_lock();
0182     ipc_lock_object(ipcp);
0183     return ipcp;
0184 }
0185 
0186 /*
0187  * Insert new IPC object into idr tree, and set sequence number and id
0188  * in the correct order.
0189  * Especially:
0190  * - the sequence number must be set before inserting the object into the idr,
0191  *   because the sequence number is accessed without a lock.
0192  * - the id can/must be set after inserting the object into the idr.
0193  *   All accesses must be done after getting kern_ipc_perm.lock.
0194  *
0195  * The caller must own kern_ipc_perm.lock.of the new object.
0196  * On error, the function returns a (negative) error code.
0197  *
0198  * To conserve sequence number space, especially with extended ipc_mni,
0199  * the sequence number is incremented only when the returned ID is less than
0200  * the last one.
0201  */
0202 static inline int ipc_idr_alloc(struct ipc_ids *ids, struct kern_ipc_perm *new)
0203 {
0204     int idx, next_id = -1;
0205 
0206 #ifdef CONFIG_CHECKPOINT_RESTORE
0207     next_id = ids->next_id;
0208     ids->next_id = -1;
0209 #endif
0210 
0211     /*
0212      * As soon as a new object is inserted into the idr,
0213      * ipc_obtain_object_idr() or ipc_obtain_object_check() can find it,
0214      * and the lockless preparations for ipc operations can start.
0215      * This means especially: permission checks, audit calls, allocation
0216      * of undo structures, ...
0217      *
0218      * Thus the object must be fully initialized, and if something fails,
0219      * then the full tear-down sequence must be followed.
0220      * (i.e.: set new->deleted, reduce refcount, call_rcu())
0221      */
0222 
0223     if (next_id < 0) { /* !CHECKPOINT_RESTORE or next_id is unset */
0224         int max_idx;
0225 
0226         max_idx = max(ids->in_use*3/2, ipc_min_cycle);
0227         max_idx = min(max_idx, ipc_mni);
0228 
0229         /* allocate the idx, with a NULL struct kern_ipc_perm */
0230         idx = idr_alloc_cyclic(&ids->ipcs_idr, NULL, 0, max_idx,
0231                     GFP_NOWAIT);
0232 
0233         if (idx >= 0) {
0234             /*
0235              * idx got allocated successfully.
0236              * Now calculate the sequence number and set the
0237              * pointer for real.
0238              */
0239             if (idx <= ids->last_idx) {
0240                 ids->seq++;
0241                 if (ids->seq >= ipcid_seq_max())
0242                     ids->seq = 0;
0243             }
0244             ids->last_idx = idx;
0245 
0246             new->seq = ids->seq;
0247             /* no need for smp_wmb(), this is done
0248              * inside idr_replace, as part of
0249              * rcu_assign_pointer
0250              */
0251             idr_replace(&ids->ipcs_idr, new, idx);
0252         }
0253     } else {
0254         new->seq = ipcid_to_seqx(next_id);
0255         idx = idr_alloc(&ids->ipcs_idr, new, ipcid_to_idx(next_id),
0256                 0, GFP_NOWAIT);
0257     }
0258     if (idx >= 0)
0259         new->id = (new->seq << ipcmni_seq_shift()) + idx;
0260     return idx;
0261 }
0262 
0263 /**
0264  * ipc_addid - add an ipc identifier
0265  * @ids: ipc identifier set
0266  * @new: new ipc permission set
0267  * @limit: limit for the number of used ids
0268  *
0269  * Add an entry 'new' to the ipc ids idr. The permissions object is
0270  * initialised and the first free entry is set up and the index assigned
0271  * is returned. The 'new' entry is returned in a locked state on success.
0272  *
0273  * On failure the entry is not locked and a negative err-code is returned.
0274  * The caller must use ipc_rcu_putref() to free the identifier.
0275  *
0276  * Called with writer ipc_ids.rwsem held.
0277  */
0278 int ipc_addid(struct ipc_ids *ids, struct kern_ipc_perm *new, int limit)
0279 {
0280     kuid_t euid;
0281     kgid_t egid;
0282     int idx, err;
0283 
0284     /* 1) Initialize the refcount so that ipc_rcu_putref works */
0285     refcount_set(&new->refcount, 1);
0286 
0287     if (limit > ipc_mni)
0288         limit = ipc_mni;
0289 
0290     if (ids->in_use >= limit)
0291         return -ENOSPC;
0292 
0293     idr_preload(GFP_KERNEL);
0294 
0295     spin_lock_init(&new->lock);
0296     rcu_read_lock();
0297     spin_lock(&new->lock);
0298 
0299     current_euid_egid(&euid, &egid);
0300     new->cuid = new->uid = euid;
0301     new->gid = new->cgid = egid;
0302 
0303     new->deleted = false;
0304 
0305     idx = ipc_idr_alloc(ids, new);
0306     idr_preload_end();
0307 
0308     if (idx >= 0 && new->key != IPC_PRIVATE) {
0309         err = rhashtable_insert_fast(&ids->key_ht, &new->khtnode,
0310                          ipc_kht_params);
0311         if (err < 0) {
0312             idr_remove(&ids->ipcs_idr, idx);
0313             idx = err;
0314         }
0315     }
0316     if (idx < 0) {
0317         new->deleted = true;
0318         spin_unlock(&new->lock);
0319         rcu_read_unlock();
0320         return idx;
0321     }
0322 
0323     ids->in_use++;
0324     if (idx > ids->max_idx)
0325         ids->max_idx = idx;
0326     return idx;
0327 }
0328 
0329 /**
0330  * ipcget_new - create a new ipc object
0331  * @ns: ipc namespace
0332  * @ids: ipc identifier set
0333  * @ops: the actual creation routine to call
0334  * @params: its parameters
0335  *
0336  * This routine is called by sys_msgget, sys_semget() and sys_shmget()
0337  * when the key is IPC_PRIVATE.
0338  */
0339 static int ipcget_new(struct ipc_namespace *ns, struct ipc_ids *ids,
0340         const struct ipc_ops *ops, struct ipc_params *params)
0341 {
0342     int err;
0343 
0344     down_write(&ids->rwsem);
0345     err = ops->getnew(ns, params);
0346     up_write(&ids->rwsem);
0347     return err;
0348 }
0349 
0350 /**
0351  * ipc_check_perms - check security and permissions for an ipc object
0352  * @ns: ipc namespace
0353  * @ipcp: ipc permission set
0354  * @ops: the actual security routine to call
0355  * @params: its parameters
0356  *
0357  * This routine is called by sys_msgget(), sys_semget() and sys_shmget()
0358  * when the key is not IPC_PRIVATE and that key already exists in the
0359  * ds IDR.
0360  *
0361  * On success, the ipc id is returned.
0362  *
0363  * It is called with ipc_ids.rwsem and ipcp->lock held.
0364  */
0365 static int ipc_check_perms(struct ipc_namespace *ns,
0366                struct kern_ipc_perm *ipcp,
0367                const struct ipc_ops *ops,
0368                struct ipc_params *params)
0369 {
0370     int err;
0371 
0372     if (ipcperms(ns, ipcp, params->flg))
0373         err = -EACCES;
0374     else {
0375         err = ops->associate(ipcp, params->flg);
0376         if (!err)
0377             err = ipcp->id;
0378     }
0379 
0380     return err;
0381 }
0382 
0383 /**
0384  * ipcget_public - get an ipc object or create a new one
0385  * @ns: ipc namespace
0386  * @ids: ipc identifier set
0387  * @ops: the actual creation routine to call
0388  * @params: its parameters
0389  *
0390  * This routine is called by sys_msgget, sys_semget() and sys_shmget()
0391  * when the key is not IPC_PRIVATE.
0392  * It adds a new entry if the key is not found and does some permission
0393  * / security checkings if the key is found.
0394  *
0395  * On success, the ipc id is returned.
0396  */
0397 static int ipcget_public(struct ipc_namespace *ns, struct ipc_ids *ids,
0398         const struct ipc_ops *ops, struct ipc_params *params)
0399 {
0400     struct kern_ipc_perm *ipcp;
0401     int flg = params->flg;
0402     int err;
0403 
0404     /*
0405      * Take the lock as a writer since we are potentially going to add
0406      * a new entry + read locks are not "upgradable"
0407      */
0408     down_write(&ids->rwsem);
0409     ipcp = ipc_findkey(ids, params->key);
0410     if (ipcp == NULL) {
0411         /* key not used */
0412         if (!(flg & IPC_CREAT))
0413             err = -ENOENT;
0414         else
0415             err = ops->getnew(ns, params);
0416     } else {
0417         /* ipc object has been locked by ipc_findkey() */
0418 
0419         if (flg & IPC_CREAT && flg & IPC_EXCL)
0420             err = -EEXIST;
0421         else {
0422             err = 0;
0423             if (ops->more_checks)
0424                 err = ops->more_checks(ipcp, params);
0425             if (!err)
0426                 /*
0427                  * ipc_check_perms returns the IPC id on
0428                  * success
0429                  */
0430                 err = ipc_check_perms(ns, ipcp, ops, params);
0431         }
0432         ipc_unlock(ipcp);
0433     }
0434     up_write(&ids->rwsem);
0435 
0436     return err;
0437 }
0438 
0439 /**
0440  * ipc_kht_remove - remove an ipc from the key hashtable
0441  * @ids: ipc identifier set
0442  * @ipcp: ipc perm structure containing the key to remove
0443  *
0444  * ipc_ids.rwsem (as a writer) and the spinlock for this ID are held
0445  * before this function is called, and remain locked on the exit.
0446  */
0447 static void ipc_kht_remove(struct ipc_ids *ids, struct kern_ipc_perm *ipcp)
0448 {
0449     if (ipcp->key != IPC_PRIVATE)
0450         WARN_ON_ONCE(rhashtable_remove_fast(&ids->key_ht, &ipcp->khtnode,
0451                        ipc_kht_params));
0452 }
0453 
0454 /**
0455  * ipc_search_maxidx - search for the highest assigned index
0456  * @ids: ipc identifier set
0457  * @limit: known upper limit for highest assigned index
0458  *
0459  * The function determines the highest assigned index in @ids. It is intended
0460  * to be called when ids->max_idx needs to be updated.
0461  * Updating ids->max_idx is necessary when the current highest index ipc
0462  * object is deleted.
0463  * If no ipc object is allocated, then -1 is returned.
0464  *
0465  * ipc_ids.rwsem needs to be held by the caller.
0466  */
0467 static int ipc_search_maxidx(struct ipc_ids *ids, int limit)
0468 {
0469     int tmpidx;
0470     int i;
0471     int retval;
0472 
0473     i = ilog2(limit+1);
0474 
0475     retval = 0;
0476     for (; i >= 0; i--) {
0477         tmpidx = retval | (1<<i);
0478         /*
0479          * "0" is a possible index value, thus search using
0480          * e.g. 15,7,3,1,0 instead of 16,8,4,2,1.
0481          */
0482         tmpidx = tmpidx-1;
0483         if (idr_get_next(&ids->ipcs_idr, &tmpidx))
0484             retval |= (1<<i);
0485     }
0486     return retval - 1;
0487 }
0488 
0489 /**
0490  * ipc_rmid - remove an ipc identifier
0491  * @ids: ipc identifier set
0492  * @ipcp: ipc perm structure containing the identifier to remove
0493  *
0494  * ipc_ids.rwsem (as a writer) and the spinlock for this ID are held
0495  * before this function is called, and remain locked on the exit.
0496  */
0497 void ipc_rmid(struct ipc_ids *ids, struct kern_ipc_perm *ipcp)
0498 {
0499     int idx = ipcid_to_idx(ipcp->id);
0500 
0501     WARN_ON_ONCE(idr_remove(&ids->ipcs_idr, idx) != ipcp);
0502     ipc_kht_remove(ids, ipcp);
0503     ids->in_use--;
0504     ipcp->deleted = true;
0505 
0506     if (unlikely(idx == ids->max_idx)) {
0507         idx = ids->max_idx-1;
0508         if (idx >= 0)
0509             idx = ipc_search_maxidx(ids, idx);
0510         ids->max_idx = idx;
0511     }
0512 }
0513 
0514 /**
0515  * ipc_set_key_private - switch the key of an existing ipc to IPC_PRIVATE
0516  * @ids: ipc identifier set
0517  * @ipcp: ipc perm structure containing the key to modify
0518  *
0519  * ipc_ids.rwsem (as a writer) and the spinlock for this ID are held
0520  * before this function is called, and remain locked on the exit.
0521  */
0522 void ipc_set_key_private(struct ipc_ids *ids, struct kern_ipc_perm *ipcp)
0523 {
0524     ipc_kht_remove(ids, ipcp);
0525     ipcp->key = IPC_PRIVATE;
0526 }
0527 
0528 bool ipc_rcu_getref(struct kern_ipc_perm *ptr)
0529 {
0530     return refcount_inc_not_zero(&ptr->refcount);
0531 }
0532 
0533 void ipc_rcu_putref(struct kern_ipc_perm *ptr,
0534             void (*func)(struct rcu_head *head))
0535 {
0536     if (!refcount_dec_and_test(&ptr->refcount))
0537         return;
0538 
0539     call_rcu(&ptr->rcu, func);
0540 }
0541 
0542 /**
0543  * ipcperms - check ipc permissions
0544  * @ns: ipc namespace
0545  * @ipcp: ipc permission set
0546  * @flag: desired permission set
0547  *
0548  * Check user, group, other permissions for access
0549  * to ipc resources. return 0 if allowed
0550  *
0551  * @flag will most probably be 0 or ``S_...UGO`` from <linux/stat.h>
0552  */
0553 int ipcperms(struct ipc_namespace *ns, struct kern_ipc_perm *ipcp, short flag)
0554 {
0555     kuid_t euid = current_euid();
0556     int requested_mode, granted_mode;
0557 
0558     audit_ipc_obj(ipcp);
0559     requested_mode = (flag >> 6) | (flag >> 3) | flag;
0560     granted_mode = ipcp->mode;
0561     if (uid_eq(euid, ipcp->cuid) ||
0562         uid_eq(euid, ipcp->uid))
0563         granted_mode >>= 6;
0564     else if (in_group_p(ipcp->cgid) || in_group_p(ipcp->gid))
0565         granted_mode >>= 3;
0566     /* is there some bit set in requested_mode but not in granted_mode? */
0567     if ((requested_mode & ~granted_mode & 0007) &&
0568         !ns_capable(ns->user_ns, CAP_IPC_OWNER))
0569         return -1;
0570 
0571     return security_ipc_permission(ipcp, flag);
0572 }
0573 
0574 /*
0575  * Functions to convert between the kern_ipc_perm structure and the
0576  * old/new ipc_perm structures
0577  */
0578 
0579 /**
0580  * kernel_to_ipc64_perm - convert kernel ipc permissions to user
0581  * @in: kernel permissions
0582  * @out: new style ipc permissions
0583  *
0584  * Turn the kernel object @in into a set of permissions descriptions
0585  * for returning to userspace (@out).
0586  */
0587 void kernel_to_ipc64_perm(struct kern_ipc_perm *in, struct ipc64_perm *out)
0588 {
0589     out->key    = in->key;
0590     out->uid    = from_kuid_munged(current_user_ns(), in->uid);
0591     out->gid    = from_kgid_munged(current_user_ns(), in->gid);
0592     out->cuid   = from_kuid_munged(current_user_ns(), in->cuid);
0593     out->cgid   = from_kgid_munged(current_user_ns(), in->cgid);
0594     out->mode   = in->mode;
0595     out->seq    = in->seq;
0596 }
0597 
0598 /**
0599  * ipc64_perm_to_ipc_perm - convert new ipc permissions to old
0600  * @in: new style ipc permissions
0601  * @out: old style ipc permissions
0602  *
0603  * Turn the new style permissions object @in into a compatibility
0604  * object and store it into the @out pointer.
0605  */
0606 void ipc64_perm_to_ipc_perm(struct ipc64_perm *in, struct ipc_perm *out)
0607 {
0608     out->key    = in->key;
0609     SET_UID(out->uid, in->uid);
0610     SET_GID(out->gid, in->gid);
0611     SET_UID(out->cuid, in->cuid);
0612     SET_GID(out->cgid, in->cgid);
0613     out->mode   = in->mode;
0614     out->seq    = in->seq;
0615 }
0616 
0617 /**
0618  * ipc_obtain_object_idr
0619  * @ids: ipc identifier set
0620  * @id: ipc id to look for
0621  *
0622  * Look for an id in the ipc ids idr and return associated ipc object.
0623  *
0624  * Call inside the RCU critical section.
0625  * The ipc object is *not* locked on exit.
0626  */
0627 struct kern_ipc_perm *ipc_obtain_object_idr(struct ipc_ids *ids, int id)
0628 {
0629     struct kern_ipc_perm *out;
0630     int idx = ipcid_to_idx(id);
0631 
0632     out = idr_find(&ids->ipcs_idr, idx);
0633     if (!out)
0634         return ERR_PTR(-EINVAL);
0635 
0636     return out;
0637 }
0638 
0639 /**
0640  * ipc_obtain_object_check
0641  * @ids: ipc identifier set
0642  * @id: ipc id to look for
0643  *
0644  * Similar to ipc_obtain_object_idr() but also checks the ipc object
0645  * sequence number.
0646  *
0647  * Call inside the RCU critical section.
0648  * The ipc object is *not* locked on exit.
0649  */
0650 struct kern_ipc_perm *ipc_obtain_object_check(struct ipc_ids *ids, int id)
0651 {
0652     struct kern_ipc_perm *out = ipc_obtain_object_idr(ids, id);
0653 
0654     if (IS_ERR(out))
0655         goto out;
0656 
0657     if (ipc_checkid(out, id))
0658         return ERR_PTR(-EINVAL);
0659 out:
0660     return out;
0661 }
0662 
0663 /**
0664  * ipcget - Common sys_*get() code
0665  * @ns: namespace
0666  * @ids: ipc identifier set
0667  * @ops: operations to be called on ipc object creation, permission checks
0668  *       and further checks
0669  * @params: the parameters needed by the previous operations.
0670  *
0671  * Common routine called by sys_msgget(), sys_semget() and sys_shmget().
0672  */
0673 int ipcget(struct ipc_namespace *ns, struct ipc_ids *ids,
0674             const struct ipc_ops *ops, struct ipc_params *params)
0675 {
0676     if (params->key == IPC_PRIVATE)
0677         return ipcget_new(ns, ids, ops, params);
0678     else
0679         return ipcget_public(ns, ids, ops, params);
0680 }
0681 
0682 /**
0683  * ipc_update_perm - update the permissions of an ipc object
0684  * @in:  the permission given as input.
0685  * @out: the permission of the ipc to set.
0686  */
0687 int ipc_update_perm(struct ipc64_perm *in, struct kern_ipc_perm *out)
0688 {
0689     kuid_t uid = make_kuid(current_user_ns(), in->uid);
0690     kgid_t gid = make_kgid(current_user_ns(), in->gid);
0691     if (!uid_valid(uid) || !gid_valid(gid))
0692         return -EINVAL;
0693 
0694     out->uid = uid;
0695     out->gid = gid;
0696     out->mode = (out->mode & ~S_IRWXUGO)
0697         | (in->mode & S_IRWXUGO);
0698 
0699     return 0;
0700 }
0701 
0702 /**
0703  * ipcctl_obtain_check - retrieve an ipc object and check permissions
0704  * @ns:  ipc namespace
0705  * @ids:  the table of ids where to look for the ipc
0706  * @id:   the id of the ipc to retrieve
0707  * @cmd:  the cmd to check
0708  * @perm: the permission to set
0709  * @extra_perm: one extra permission parameter used by msq
0710  *
0711  * This function does some common audit and permissions check for some IPC_XXX
0712  * cmd and is called from semctl_down, shmctl_down and msgctl_down.
0713  *
0714  * It:
0715  *   - retrieves the ipc object with the given id in the given table.
0716  *   - performs some audit and permission check, depending on the given cmd
0717  *   - returns a pointer to the ipc object or otherwise, the corresponding
0718  *     error.
0719  *
0720  * Call holding the both the rwsem and the rcu read lock.
0721  */
0722 struct kern_ipc_perm *ipcctl_obtain_check(struct ipc_namespace *ns,
0723                     struct ipc_ids *ids, int id, int cmd,
0724                     struct ipc64_perm *perm, int extra_perm)
0725 {
0726     kuid_t euid;
0727     int err = -EPERM;
0728     struct kern_ipc_perm *ipcp;
0729 
0730     ipcp = ipc_obtain_object_check(ids, id);
0731     if (IS_ERR(ipcp)) {
0732         err = PTR_ERR(ipcp);
0733         goto err;
0734     }
0735 
0736     audit_ipc_obj(ipcp);
0737     if (cmd == IPC_SET)
0738         audit_ipc_set_perm(extra_perm, perm->uid,
0739                    perm->gid, perm->mode);
0740 
0741     euid = current_euid();
0742     if (uid_eq(euid, ipcp->cuid) || uid_eq(euid, ipcp->uid)  ||
0743         ns_capable(ns->user_ns, CAP_SYS_ADMIN))
0744         return ipcp; /* successful lookup */
0745 err:
0746     return ERR_PTR(err);
0747 }
0748 
0749 #ifdef CONFIG_ARCH_WANT_IPC_PARSE_VERSION
0750 
0751 
0752 /**
0753  * ipc_parse_version - ipc call version
0754  * @cmd: pointer to command
0755  *
0756  * Return IPC_64 for new style IPC and IPC_OLD for old style IPC.
0757  * The @cmd value is turned from an encoding command and version into
0758  * just the command code.
0759  */
0760 int ipc_parse_version(int *cmd)
0761 {
0762     if (*cmd & IPC_64) {
0763         *cmd ^= IPC_64;
0764         return IPC_64;
0765     } else {
0766         return IPC_OLD;
0767     }
0768 }
0769 
0770 #endif /* CONFIG_ARCH_WANT_IPC_PARSE_VERSION */
0771 
0772 #ifdef CONFIG_PROC_FS
0773 struct ipc_proc_iter {
0774     struct ipc_namespace *ns;
0775     struct pid_namespace *pid_ns;
0776     struct ipc_proc_iface *iface;
0777 };
0778 
0779 struct pid_namespace *ipc_seq_pid_ns(struct seq_file *s)
0780 {
0781     struct ipc_proc_iter *iter = s->private;
0782     return iter->pid_ns;
0783 }
0784 
0785 /*
0786  * This routine locks the ipc structure found at least at position pos.
0787  */
0788 static struct kern_ipc_perm *sysvipc_find_ipc(struct ipc_ids *ids, loff_t pos,
0789                           loff_t *new_pos)
0790 {
0791     struct kern_ipc_perm *ipc = NULL;
0792     int max_idx = ipc_get_maxidx(ids);
0793 
0794     if (max_idx == -1 || pos > max_idx)
0795         goto out;
0796 
0797     for (; pos <= max_idx; pos++) {
0798         ipc = idr_find(&ids->ipcs_idr, pos);
0799         if (ipc != NULL) {
0800             rcu_read_lock();
0801             ipc_lock_object(ipc);
0802             break;
0803         }
0804     }
0805 out:
0806     *new_pos = pos + 1;
0807     return ipc;
0808 }
0809 
0810 static void *sysvipc_proc_next(struct seq_file *s, void *it, loff_t *pos)
0811 {
0812     struct ipc_proc_iter *iter = s->private;
0813     struct ipc_proc_iface *iface = iter->iface;
0814     struct kern_ipc_perm *ipc = it;
0815 
0816     /* If we had an ipc id locked before, unlock it */
0817     if (ipc && ipc != SEQ_START_TOKEN)
0818         ipc_unlock(ipc);
0819 
0820     return sysvipc_find_ipc(&iter->ns->ids[iface->ids], *pos, pos);
0821 }
0822 
0823 /*
0824  * File positions: pos 0 -> header, pos n -> ipc id = n - 1.
0825  * SeqFile iterator: iterator value locked ipc pointer or SEQ_TOKEN_START.
0826  */
0827 static void *sysvipc_proc_start(struct seq_file *s, loff_t *pos)
0828 {
0829     struct ipc_proc_iter *iter = s->private;
0830     struct ipc_proc_iface *iface = iter->iface;
0831     struct ipc_ids *ids;
0832 
0833     ids = &iter->ns->ids[iface->ids];
0834 
0835     /*
0836      * Take the lock - this will be released by the corresponding
0837      * call to stop().
0838      */
0839     down_read(&ids->rwsem);
0840 
0841     /* pos < 0 is invalid */
0842     if (*pos < 0)
0843         return NULL;
0844 
0845     /* pos == 0 means header */
0846     if (*pos == 0)
0847         return SEQ_START_TOKEN;
0848 
0849     /* Find the (pos-1)th ipc */
0850     return sysvipc_find_ipc(ids, *pos - 1, pos);
0851 }
0852 
0853 static void sysvipc_proc_stop(struct seq_file *s, void *it)
0854 {
0855     struct kern_ipc_perm *ipc = it;
0856     struct ipc_proc_iter *iter = s->private;
0857     struct ipc_proc_iface *iface = iter->iface;
0858     struct ipc_ids *ids;
0859 
0860     /* If we had a locked structure, release it */
0861     if (ipc && ipc != SEQ_START_TOKEN)
0862         ipc_unlock(ipc);
0863 
0864     ids = &iter->ns->ids[iface->ids];
0865     /* Release the lock we took in start() */
0866     up_read(&ids->rwsem);
0867 }
0868 
0869 static int sysvipc_proc_show(struct seq_file *s, void *it)
0870 {
0871     struct ipc_proc_iter *iter = s->private;
0872     struct ipc_proc_iface *iface = iter->iface;
0873 
0874     if (it == SEQ_START_TOKEN) {
0875         seq_puts(s, iface->header);
0876         return 0;
0877     }
0878 
0879     return iface->show(s, it);
0880 }
0881 
0882 static const struct seq_operations sysvipc_proc_seqops = {
0883     .start = sysvipc_proc_start,
0884     .stop  = sysvipc_proc_stop,
0885     .next  = sysvipc_proc_next,
0886     .show  = sysvipc_proc_show,
0887 };
0888 
0889 static int sysvipc_proc_open(struct inode *inode, struct file *file)
0890 {
0891     struct ipc_proc_iter *iter;
0892 
0893     iter = __seq_open_private(file, &sysvipc_proc_seqops, sizeof(*iter));
0894     if (!iter)
0895         return -ENOMEM;
0896 
0897     iter->iface = pde_data(inode);
0898     iter->ns    = get_ipc_ns(current->nsproxy->ipc_ns);
0899     iter->pid_ns = get_pid_ns(task_active_pid_ns(current));
0900 
0901     return 0;
0902 }
0903 
0904 static int sysvipc_proc_release(struct inode *inode, struct file *file)
0905 {
0906     struct seq_file *seq = file->private_data;
0907     struct ipc_proc_iter *iter = seq->private;
0908     put_ipc_ns(iter->ns);
0909     put_pid_ns(iter->pid_ns);
0910     return seq_release_private(inode, file);
0911 }
0912 
0913 static const struct proc_ops sysvipc_proc_ops = {
0914     .proc_flags = PROC_ENTRY_PERMANENT,
0915     .proc_open  = sysvipc_proc_open,
0916     .proc_read  = seq_read,
0917     .proc_lseek = seq_lseek,
0918     .proc_release   = sysvipc_proc_release,
0919 };
0920 #endif /* CONFIG_PROC_FS */