0001
0002
0003
0004
0005
0006
0007 #include <linux/ipc.h>
0008 #include <linux/msg.h>
0009 #include <linux/ipc_namespace.h>
0010 #include <linux/rcupdate.h>
0011 #include <linux/nsproxy.h>
0012 #include <linux/slab.h>
0013 #include <linux/cred.h>
0014 #include <linux/fs.h>
0015 #include <linux/mount.h>
0016 #include <linux/user_namespace.h>
0017 #include <linux/proc_ns.h>
0018 #include <linux/sched/task.h>
0019
0020 #include "util.h"
0021
0022 static struct ucounts *inc_ipc_namespaces(struct user_namespace *ns)
0023 {
0024 return inc_ucount(ns, current_euid(), UCOUNT_IPC_NAMESPACES);
0025 }
0026
0027 static void dec_ipc_namespaces(struct ucounts *ucounts)
0028 {
0029 dec_ucount(ucounts, UCOUNT_IPC_NAMESPACES);
0030 }
0031
0032 static struct ipc_namespace *create_ipc_ns(struct user_namespace *user_ns,
0033 struct ipc_namespace *old_ns)
0034 {
0035 struct ipc_namespace *ns;
0036 struct ucounts *ucounts;
0037 int err;
0038
0039 err = -ENOSPC;
0040 ucounts = inc_ipc_namespaces(user_ns);
0041 if (!ucounts)
0042 goto fail;
0043
0044 err = -ENOMEM;
0045 ns = kzalloc(sizeof(struct ipc_namespace), GFP_KERNEL_ACCOUNT);
0046 if (ns == NULL)
0047 goto fail_dec;
0048
0049 err = ns_alloc_inum(&ns->ns);
0050 if (err)
0051 goto fail_free;
0052 ns->ns.ops = &ipcns_operations;
0053
0054 refcount_set(&ns->ns.count, 1);
0055 ns->user_ns = get_user_ns(user_ns);
0056 ns->ucounts = ucounts;
0057
0058 err = mq_init_ns(ns);
0059 if (err)
0060 goto fail_put;
0061
0062 err = -ENOMEM;
0063 if (!setup_mq_sysctls(ns))
0064 goto fail_put;
0065
0066 if (!setup_ipc_sysctls(ns))
0067 goto fail_mq;
0068
0069 sem_init_ns(ns);
0070 msg_init_ns(ns);
0071 shm_init_ns(ns);
0072
0073 return ns;
0074
0075 fail_mq:
0076 retire_mq_sysctls(ns);
0077
0078 fail_put:
0079 put_user_ns(ns->user_ns);
0080 ns_free_inum(&ns->ns);
0081 fail_free:
0082 kfree(ns);
0083 fail_dec:
0084 dec_ipc_namespaces(ucounts);
0085 fail:
0086 return ERR_PTR(err);
0087 }
0088
0089 struct ipc_namespace *copy_ipcs(unsigned long flags,
0090 struct user_namespace *user_ns, struct ipc_namespace *ns)
0091 {
0092 if (!(flags & CLONE_NEWIPC))
0093 return get_ipc_ns(ns);
0094 return create_ipc_ns(user_ns, ns);
0095 }
0096
0097
0098
0099
0100
0101
0102
0103
0104
0105 void free_ipcs(struct ipc_namespace *ns, struct ipc_ids *ids,
0106 void (*free)(struct ipc_namespace *, struct kern_ipc_perm *))
0107 {
0108 struct kern_ipc_perm *perm;
0109 int next_id;
0110 int total, in_use;
0111
0112 down_write(&ids->rwsem);
0113
0114 in_use = ids->in_use;
0115
0116 for (total = 0, next_id = 0; total < in_use; next_id++) {
0117 perm = idr_find(&ids->ipcs_idr, next_id);
0118 if (perm == NULL)
0119 continue;
0120 rcu_read_lock();
0121 ipc_lock_object(perm);
0122 free(ns, perm);
0123 total++;
0124 }
0125 up_write(&ids->rwsem);
0126 }
0127
0128 static void free_ipc_ns(struct ipc_namespace *ns)
0129 {
0130
0131
0132
0133 mq_put_mnt(ns);
0134 sem_exit_ns(ns);
0135 msg_exit_ns(ns);
0136 shm_exit_ns(ns);
0137
0138 retire_mq_sysctls(ns);
0139 retire_ipc_sysctls(ns);
0140
0141 dec_ipc_namespaces(ns->ucounts);
0142 put_user_ns(ns->user_ns);
0143 ns_free_inum(&ns->ns);
0144 kfree(ns);
0145 }
0146
0147 static LLIST_HEAD(free_ipc_list);
0148 static void free_ipc(struct work_struct *unused)
0149 {
0150 struct llist_node *node = llist_del_all(&free_ipc_list);
0151 struct ipc_namespace *n, *t;
0152
0153 llist_for_each_entry_safe(n, t, node, mnt_llist)
0154 free_ipc_ns(n);
0155 }
0156
0157
0158
0159
0160 static DECLARE_WORK(free_ipc_work, free_ipc);
0161
0162
0163
0164
0165
0166
0167
0168
0169
0170
0171
0172
0173
0174
0175
0176
0177
0178 void put_ipc_ns(struct ipc_namespace *ns)
0179 {
0180 if (refcount_dec_and_lock(&ns->ns.count, &mq_lock)) {
0181 mq_clear_sbinfo(ns);
0182 spin_unlock(&mq_lock);
0183
0184 if (llist_add(&ns->mnt_llist, &free_ipc_list))
0185 schedule_work(&free_ipc_work);
0186 }
0187 }
0188
0189 static inline struct ipc_namespace *to_ipc_ns(struct ns_common *ns)
0190 {
0191 return container_of(ns, struct ipc_namespace, ns);
0192 }
0193
0194 static struct ns_common *ipcns_get(struct task_struct *task)
0195 {
0196 struct ipc_namespace *ns = NULL;
0197 struct nsproxy *nsproxy;
0198
0199 task_lock(task);
0200 nsproxy = task->nsproxy;
0201 if (nsproxy)
0202 ns = get_ipc_ns(nsproxy->ipc_ns);
0203 task_unlock(task);
0204
0205 return ns ? &ns->ns : NULL;
0206 }
0207
0208 static void ipcns_put(struct ns_common *ns)
0209 {
0210 return put_ipc_ns(to_ipc_ns(ns));
0211 }
0212
0213 static int ipcns_install(struct nsset *nsset, struct ns_common *new)
0214 {
0215 struct nsproxy *nsproxy = nsset->nsproxy;
0216 struct ipc_namespace *ns = to_ipc_ns(new);
0217 if (!ns_capable(ns->user_ns, CAP_SYS_ADMIN) ||
0218 !ns_capable(nsset->cred->user_ns, CAP_SYS_ADMIN))
0219 return -EPERM;
0220
0221 put_ipc_ns(nsproxy->ipc_ns);
0222 nsproxy->ipc_ns = get_ipc_ns(ns);
0223 return 0;
0224 }
0225
0226 static struct user_namespace *ipcns_owner(struct ns_common *ns)
0227 {
0228 return to_ipc_ns(ns)->user_ns;
0229 }
0230
0231 const struct proc_ns_operations ipcns_operations = {
0232 .name = "ipc",
0233 .type = CLONE_NEWIPC,
0234 .get = ipcns_get,
0235 .put = ipcns_put,
0236 .install = ipcns_install,
0237 .owner = ipcns_owner,
0238 };