aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ipc/shm.c254
1 files changed, 168 insertions, 86 deletions
diff --git a/ipc/shm.c b/ipc/shm.c
index 940b0c9b13aa..bfbd317ec11c 100644
--- a/ipc/shm.c
+++ b/ipc/shm.c
@@ -15,6 +15,10 @@
15 * 15 *
16 * support for audit of ipc object properties and permission changes 16 * support for audit of ipc object properties and permission changes
17 * Dustin Kirkland <dustin.kirkland@us.ibm.com> 17 * Dustin Kirkland <dustin.kirkland@us.ibm.com>
18 *
19 * namespaces support
20 * OpenVZ, SWsoft Inc.
21 * Pavel Emelianov <xemul@openvz.org>
18 */ 22 */
19 23
20#include <linux/slab.h> 24#include <linux/slab.h>
@@ -32,6 +36,7 @@
32#include <linux/ptrace.h> 36#include <linux/ptrace.h>
33#include <linux/seq_file.h> 37#include <linux/seq_file.h>
34#include <linux/mutex.h> 38#include <linux/mutex.h>
39#include <linux/nsproxy.h>
35 40
36#include <asm/uaccess.h> 41#include <asm/uaccess.h>
37 42
@@ -40,59 +45,115 @@
40static struct file_operations shm_file_operations; 45static struct file_operations shm_file_operations;
41static struct vm_operations_struct shm_vm_ops; 46static struct vm_operations_struct shm_vm_ops;
42 47
43static struct ipc_ids shm_ids; 48static struct ipc_ids init_shm_ids;
49
50#define shm_ids(ns) (*((ns)->ids[IPC_SHM_IDS]))
44 51
45#define shm_lock(id) ((struct shmid_kernel*)ipc_lock(&shm_ids,id)) 52#define shm_lock(ns, id) \
46#define shm_unlock(shp) ipc_unlock(&(shp)->shm_perm) 53 ((struct shmid_kernel*)ipc_lock(&shm_ids(ns),id))
47#define shm_get(id) ((struct shmid_kernel*)ipc_get(&shm_ids,id)) 54#define shm_unlock(shp) \
48#define shm_buildid(id, seq) \ 55 ipc_unlock(&(shp)->shm_perm)
49 ipc_buildid(&shm_ids, id, seq) 56#define shm_get(ns, id) \
57 ((struct shmid_kernel*)ipc_get(&shm_ids(ns),id))
58#define shm_buildid(ns, id, seq) \
59 ipc_buildid(&shm_ids(ns), id, seq)
50 60
51static int newseg (key_t key, int shmflg, size_t size); 61static int newseg (struct ipc_namespace *ns, key_t key,
62 int shmflg, size_t size);
52static void shm_open (struct vm_area_struct *shmd); 63static void shm_open (struct vm_area_struct *shmd);
53static void shm_close (struct vm_area_struct *shmd); 64static void shm_close (struct vm_area_struct *shmd);
65static void shm_destroy (struct ipc_namespace *ns, struct shmid_kernel *shp);
54#ifdef CONFIG_PROC_FS 66#ifdef CONFIG_PROC_FS
55static int sysvipc_shm_proc_show(struct seq_file *s, void *it); 67static int sysvipc_shm_proc_show(struct seq_file *s, void *it);
56#endif 68#endif
57 69
58size_t shm_ctlmax = SHMMAX; 70static void __ipc_init __shm_init_ns(struct ipc_namespace *ns, struct ipc_ids *ids)
59size_t shm_ctlall = SHMALL; 71{
60int shm_ctlmni = SHMMNI; 72 ns->ids[IPC_SHM_IDS] = ids;
73 ns->shm_ctlmax = SHMMAX;
74 ns->shm_ctlall = SHMALL;
75 ns->shm_ctlmni = SHMMNI;
76 ns->shm_tot = 0;
77 ipc_init_ids(ids, 1);
78}
79
80static void do_shm_rmid(struct ipc_namespace *ns, struct shmid_kernel *shp)
81{
82 if (shp->shm_nattch){
83 shp->shm_perm.mode |= SHM_DEST;
84 /* Do not find it any more */
85 shp->shm_perm.key = IPC_PRIVATE;
86 shm_unlock(shp);
87 } else
88 shm_destroy(ns, shp);
89}
90
91#ifdef CONFIG_IPC_NS
92int shm_init_ns(struct ipc_namespace *ns)
93{
94 struct ipc_ids *ids;
95
96 ids = kmalloc(sizeof(struct ipc_ids), GFP_KERNEL);
97 if (ids == NULL)
98 return -ENOMEM;
61 99
62static int shm_tot; /* total number of shared memory pages */ 100 __shm_init_ns(ns, ids);
101 return 0;
102}
103
104void shm_exit_ns(struct ipc_namespace *ns)
105{
106 int i;
107 struct shmid_kernel *shp;
108
109 mutex_lock(&shm_ids(ns).mutex);
110 for (i = 0; i <= shm_ids(ns).max_id; i++) {
111 shp = shm_lock(ns, i);
112 if (shp == NULL)
113 continue;
114
115 do_shm_rmid(ns, shp);
116 }
117 mutex_unlock(&shm_ids(ns).mutex);
118
119 kfree(ns->ids[IPC_SHM_IDS]);
120 ns->ids[IPC_SHM_IDS] = NULL;
121}
122#endif
63 123
64void __init shm_init (void) 124void __init shm_init (void)
65{ 125{
66 ipc_init_ids(&shm_ids, 1); 126 __shm_init_ns(&init_ipc_ns, &init_shm_ids);
67 ipc_init_proc_interface("sysvipc/shm", 127 ipc_init_proc_interface("sysvipc/shm",
68 " key shmid perms size cpid lpid nattch uid gid cuid cgid atime dtime ctime\n", 128 " key shmid perms size cpid lpid nattch uid gid cuid cgid atime dtime ctime\n",
69 &shm_ids, 129 IPC_SHM_IDS, sysvipc_shm_proc_show);
70 sysvipc_shm_proc_show);
71} 130}
72 131
73static inline int shm_checkid(struct shmid_kernel *s, int id) 132static inline int shm_checkid(struct ipc_namespace *ns,
133 struct shmid_kernel *s, int id)
74{ 134{
75 if (ipc_checkid(&shm_ids,&s->shm_perm,id)) 135 if (ipc_checkid(&shm_ids(ns), &s->shm_perm, id))
76 return -EIDRM; 136 return -EIDRM;
77 return 0; 137 return 0;
78} 138}
79 139
80static inline struct shmid_kernel *shm_rmid(int id) 140static inline struct shmid_kernel *shm_rmid(struct ipc_namespace *ns, int id)
81{ 141{
82 return (struct shmid_kernel *)ipc_rmid(&shm_ids,id); 142 return (struct shmid_kernel *)ipc_rmid(&shm_ids(ns), id);
83} 143}
84 144
85static inline int shm_addid(struct shmid_kernel *shp) 145static inline int shm_addid(struct ipc_namespace *ns, struct shmid_kernel *shp)
86{ 146{
87 return ipc_addid(&shm_ids, &shp->shm_perm, shm_ctlmni); 147 return ipc_addid(&shm_ids(ns), &shp->shm_perm, ns->shm_ctlmni);
88} 148}
89 149
90 150
91 151
92static inline void shm_inc (int id) { 152static inline void shm_inc(struct ipc_namespace *ns, int id)
153{
93 struct shmid_kernel *shp; 154 struct shmid_kernel *shp;
94 155
95 shp = shm_lock(id); 156 shp = shm_lock(ns, id);
96 BUG_ON(!shp); 157 BUG_ON(!shp);
97 shp->shm_atim = get_seconds(); 158 shp->shm_atim = get_seconds();
98 shp->shm_lprid = current->tgid; 159 shp->shm_lprid = current->tgid;
@@ -100,10 +161,13 @@ static inline void shm_inc (int id) {
100 shm_unlock(shp); 161 shm_unlock(shp);
101} 162}
102 163
164#define shm_file_ns(file) (*((struct ipc_namespace **)&(file)->private_data))
165
103/* This is called by fork, once for every shm attach. */ 166/* This is called by fork, once for every shm attach. */
104static void shm_open (struct vm_area_struct *shmd) 167static void shm_open(struct vm_area_struct *shmd)
105{ 168{
106 shm_inc (shmd->vm_file->f_dentry->d_inode->i_ino); 169 shm_inc(shm_file_ns(shmd->vm_file),
170 shmd->vm_file->f_dentry->d_inode->i_ino);
107} 171}
108 172
109/* 173/*
@@ -114,10 +178,10 @@ static void shm_open (struct vm_area_struct *shmd)
114 * It has to be called with shp and shm_ids.mutex locked, 178 * It has to be called with shp and shm_ids.mutex locked,
115 * but returns with shp unlocked and freed. 179 * but returns with shp unlocked and freed.
116 */ 180 */
117static void shm_destroy (struct shmid_kernel *shp) 181static void shm_destroy(struct ipc_namespace *ns, struct shmid_kernel *shp)
118{ 182{
119 shm_tot -= (shp->shm_segsz + PAGE_SIZE - 1) >> PAGE_SHIFT; 183 ns->shm_tot -= (shp->shm_segsz + PAGE_SIZE - 1) >> PAGE_SHIFT;
120 shm_rmid (shp->id); 184 shm_rmid(ns, shp->id);
121 shm_unlock(shp); 185 shm_unlock(shp);
122 if (!is_file_hugepages(shp->shm_file)) 186 if (!is_file_hugepages(shp->shm_file))
123 shmem_lock(shp->shm_file, 0, shp->mlock_user); 187 shmem_lock(shp->shm_file, 0, shp->mlock_user);
@@ -140,20 +204,23 @@ static void shm_close (struct vm_area_struct *shmd)
140 struct file * file = shmd->vm_file; 204 struct file * file = shmd->vm_file;
141 int id = file->f_dentry->d_inode->i_ino; 205 int id = file->f_dentry->d_inode->i_ino;
142 struct shmid_kernel *shp; 206 struct shmid_kernel *shp;
207 struct ipc_namespace *ns;
143 208
144 mutex_lock(&shm_ids.mutex); 209 ns = shm_file_ns(file);
210
211 mutex_lock(&shm_ids(ns).mutex);
145 /* remove from the list of attaches of the shm segment */ 212 /* remove from the list of attaches of the shm segment */
146 shp = shm_lock(id); 213 shp = shm_lock(ns, id);
147 BUG_ON(!shp); 214 BUG_ON(!shp);
148 shp->shm_lprid = current->tgid; 215 shp->shm_lprid = current->tgid;
149 shp->shm_dtim = get_seconds(); 216 shp->shm_dtim = get_seconds();
150 shp->shm_nattch--; 217 shp->shm_nattch--;
151 if(shp->shm_nattch == 0 && 218 if(shp->shm_nattch == 0 &&
152 shp->shm_perm.mode & SHM_DEST) 219 shp->shm_perm.mode & SHM_DEST)
153 shm_destroy (shp); 220 shm_destroy(ns, shp);
154 else 221 else
155 shm_unlock(shp); 222 shm_unlock(shp);
156 mutex_unlock(&shm_ids.mutex); 223 mutex_unlock(&shm_ids(ns).mutex);
157} 224}
158 225
159static int shm_mmap(struct file * file, struct vm_area_struct * vma) 226static int shm_mmap(struct file * file, struct vm_area_struct * vma)
@@ -165,14 +232,25 @@ static int shm_mmap(struct file * file, struct vm_area_struct * vma)
165 vma->vm_ops = &shm_vm_ops; 232 vma->vm_ops = &shm_vm_ops;
166 if (!(vma->vm_flags & VM_WRITE)) 233 if (!(vma->vm_flags & VM_WRITE))
167 vma->vm_flags &= ~VM_MAYWRITE; 234 vma->vm_flags &= ~VM_MAYWRITE;
168 shm_inc(file->f_dentry->d_inode->i_ino); 235 shm_inc(shm_file_ns(file), file->f_dentry->d_inode->i_ino);
169 } 236 }
170 237
171 return ret; 238 return ret;
172} 239}
173 240
241static int shm_release(struct inode *ino, struct file *file)
242{
243 struct ipc_namespace *ns;
244
245 ns = shm_file_ns(file);
246 put_ipc_ns(ns);
247 shm_file_ns(file) = NULL;
248 return 0;
249}
250
174static struct file_operations shm_file_operations = { 251static struct file_operations shm_file_operations = {
175 .mmap = shm_mmap, 252 .mmap = shm_mmap,
253 .release = shm_release,
176#ifndef CONFIG_MMU 254#ifndef CONFIG_MMU
177 .get_unmapped_area = shmem_get_unmapped_area, 255 .get_unmapped_area = shmem_get_unmapped_area,
178#endif 256#endif
@@ -188,7 +266,7 @@ static struct vm_operations_struct shm_vm_ops = {
188#endif 266#endif
189}; 267};
190 268
191static int newseg (key_t key, int shmflg, size_t size) 269static int newseg (struct ipc_namespace *ns, key_t key, int shmflg, size_t size)
192{ 270{
193 int error; 271 int error;
194 struct shmid_kernel *shp; 272 struct shmid_kernel *shp;
@@ -197,10 +275,10 @@ static int newseg (key_t key, int shmflg, size_t size)
197 char name[13]; 275 char name[13];
198 int id; 276 int id;
199 277
200 if (size < SHMMIN || size > shm_ctlmax) 278 if (size < SHMMIN || size > ns->shm_ctlmax)
201 return -EINVAL; 279 return -EINVAL;
202 280
203 if (shm_tot + numpages >= shm_ctlall) 281 if (ns->shm_tot + numpages >= ns->shm_ctlall)
204 return -ENOSPC; 282 return -ENOSPC;
205 283
206 shp = ipc_rcu_alloc(sizeof(*shp)); 284 shp = ipc_rcu_alloc(sizeof(*shp));
@@ -239,7 +317,7 @@ static int newseg (key_t key, int shmflg, size_t size)
239 goto no_file; 317 goto no_file;
240 318
241 error = -ENOSPC; 319 error = -ENOSPC;
242 id = shm_addid(shp); 320 id = shm_addid(ns, shp);
243 if(id == -1) 321 if(id == -1)
244 goto no_id; 322 goto no_id;
245 323
@@ -249,15 +327,17 @@ static int newseg (key_t key, int shmflg, size_t size)
249 shp->shm_ctim = get_seconds(); 327 shp->shm_ctim = get_seconds();
250 shp->shm_segsz = size; 328 shp->shm_segsz = size;
251 shp->shm_nattch = 0; 329 shp->shm_nattch = 0;
252 shp->id = shm_buildid(id,shp->shm_perm.seq); 330 shp->id = shm_buildid(ns, id, shp->shm_perm.seq);
253 shp->shm_file = file; 331 shp->shm_file = file;
254 file->f_dentry->d_inode->i_ino = shp->id; 332 file->f_dentry->d_inode->i_ino = shp->id;
255 333
334 shm_file_ns(file) = get_ipc_ns(ns);
335
256 /* Hugetlb ops would have already been assigned. */ 336 /* Hugetlb ops would have already been assigned. */
257 if (!(shmflg & SHM_HUGETLB)) 337 if (!(shmflg & SHM_HUGETLB))
258 file->f_op = &shm_file_operations; 338 file->f_op = &shm_file_operations;
259 339
260 shm_tot += numpages; 340 ns->shm_tot += numpages;
261 shm_unlock(shp); 341 shm_unlock(shp);
262 return shp->id; 342 return shp->id;
263 343
@@ -273,33 +353,36 @@ asmlinkage long sys_shmget (key_t key, size_t size, int shmflg)
273{ 353{
274 struct shmid_kernel *shp; 354 struct shmid_kernel *shp;
275 int err, id = 0; 355 int err, id = 0;
356 struct ipc_namespace *ns;
357
358 ns = current->nsproxy->ipc_ns;
276 359
277 mutex_lock(&shm_ids.mutex); 360 mutex_lock(&shm_ids(ns).mutex);
278 if (key == IPC_PRIVATE) { 361 if (key == IPC_PRIVATE) {
279 err = newseg(key, shmflg, size); 362 err = newseg(ns, key, shmflg, size);
280 } else if ((id = ipc_findkey(&shm_ids, key)) == -1) { 363 } else if ((id = ipc_findkey(&shm_ids(ns), key)) == -1) {
281 if (!(shmflg & IPC_CREAT)) 364 if (!(shmflg & IPC_CREAT))
282 err = -ENOENT; 365 err = -ENOENT;
283 else 366 else
284 err = newseg(key, shmflg, size); 367 err = newseg(ns, key, shmflg, size);
285 } else if ((shmflg & IPC_CREAT) && (shmflg & IPC_EXCL)) { 368 } else if ((shmflg & IPC_CREAT) && (shmflg & IPC_EXCL)) {
286 err = -EEXIST; 369 err = -EEXIST;
287 } else { 370 } else {
288 shp = shm_lock(id); 371 shp = shm_lock(ns, id);
289 BUG_ON(shp==NULL); 372 BUG_ON(shp==NULL);
290 if (shp->shm_segsz < size) 373 if (shp->shm_segsz < size)
291 err = -EINVAL; 374 err = -EINVAL;
292 else if (ipcperms(&shp->shm_perm, shmflg)) 375 else if (ipcperms(&shp->shm_perm, shmflg))
293 err = -EACCES; 376 err = -EACCES;
294 else { 377 else {
295 int shmid = shm_buildid(id, shp->shm_perm.seq); 378 int shmid = shm_buildid(ns, id, shp->shm_perm.seq);
296 err = security_shm_associate(shp, shmflg); 379 err = security_shm_associate(shp, shmflg);
297 if (!err) 380 if (!err)
298 err = shmid; 381 err = shmid;
299 } 382 }
300 shm_unlock(shp); 383 shm_unlock(shp);
301 } 384 }
302 mutex_unlock(&shm_ids.mutex); 385 mutex_unlock(&shm_ids(ns).mutex);
303 386
304 return err; 387 return err;
305} 388}
@@ -395,18 +478,19 @@ static inline unsigned long copy_shminfo_to_user(void __user *buf, struct shminf
395 } 478 }
396} 479}
397 480
398static void shm_get_stat(unsigned long *rss, unsigned long *swp) 481static void shm_get_stat(struct ipc_namespace *ns, unsigned long *rss,
482 unsigned long *swp)
399{ 483{
400 int i; 484 int i;
401 485
402 *rss = 0; 486 *rss = 0;
403 *swp = 0; 487 *swp = 0;
404 488
405 for (i = 0; i <= shm_ids.max_id; i++) { 489 for (i = 0; i <= shm_ids(ns).max_id; i++) {
406 struct shmid_kernel *shp; 490 struct shmid_kernel *shp;
407 struct inode *inode; 491 struct inode *inode;
408 492
409 shp = shm_get(i); 493 shp = shm_get(ns, i);
410 if(!shp) 494 if(!shp)
411 continue; 495 continue;
412 496
@@ -430,6 +514,7 @@ asmlinkage long sys_shmctl (int shmid, int cmd, struct shmid_ds __user *buf)
430 struct shm_setbuf setbuf; 514 struct shm_setbuf setbuf;
431 struct shmid_kernel *shp; 515 struct shmid_kernel *shp;
432 int err, version; 516 int err, version;
517 struct ipc_namespace *ns;
433 518
434 if (cmd < 0 || shmid < 0) { 519 if (cmd < 0 || shmid < 0) {
435 err = -EINVAL; 520 err = -EINVAL;
@@ -437,6 +522,7 @@ asmlinkage long sys_shmctl (int shmid, int cmd, struct shmid_ds __user *buf)
437 } 522 }
438 523
439 version = ipc_parse_version(&cmd); 524 version = ipc_parse_version(&cmd);
525 ns = current->nsproxy->ipc_ns;
440 526
441 switch (cmd) { /* replace with proc interface ? */ 527 switch (cmd) { /* replace with proc interface ? */
442 case IPC_INFO: 528 case IPC_INFO:
@@ -448,15 +534,15 @@ asmlinkage long sys_shmctl (int shmid, int cmd, struct shmid_ds __user *buf)
448 return err; 534 return err;
449 535
450 memset(&shminfo,0,sizeof(shminfo)); 536 memset(&shminfo,0,sizeof(shminfo));
451 shminfo.shmmni = shminfo.shmseg = shm_ctlmni; 537 shminfo.shmmni = shminfo.shmseg = ns->shm_ctlmni;
452 shminfo.shmmax = shm_ctlmax; 538 shminfo.shmmax = ns->shm_ctlmax;
453 shminfo.shmall = shm_ctlall; 539 shminfo.shmall = ns->shm_ctlall;
454 540
455 shminfo.shmmin = SHMMIN; 541 shminfo.shmmin = SHMMIN;
456 if(copy_shminfo_to_user (buf, &shminfo, version)) 542 if(copy_shminfo_to_user (buf, &shminfo, version))
457 return -EFAULT; 543 return -EFAULT;
458 /* reading a integer is always atomic */ 544 /* reading a integer is always atomic */
459 err= shm_ids.max_id; 545 err= shm_ids(ns).max_id;
460 if(err<0) 546 if(err<0)
461 err = 0; 547 err = 0;
462 goto out; 548 goto out;
@@ -470,14 +556,14 @@ asmlinkage long sys_shmctl (int shmid, int cmd, struct shmid_ds __user *buf)
470 return err; 556 return err;
471 557
472 memset(&shm_info,0,sizeof(shm_info)); 558 memset(&shm_info,0,sizeof(shm_info));
473 mutex_lock(&shm_ids.mutex); 559 mutex_lock(&shm_ids(ns).mutex);
474 shm_info.used_ids = shm_ids.in_use; 560 shm_info.used_ids = shm_ids(ns).in_use;
475 shm_get_stat (&shm_info.shm_rss, &shm_info.shm_swp); 561 shm_get_stat (ns, &shm_info.shm_rss, &shm_info.shm_swp);
476 shm_info.shm_tot = shm_tot; 562 shm_info.shm_tot = ns->shm_tot;
477 shm_info.swap_attempts = 0; 563 shm_info.swap_attempts = 0;
478 shm_info.swap_successes = 0; 564 shm_info.swap_successes = 0;
479 err = shm_ids.max_id; 565 err = shm_ids(ns).max_id;
480 mutex_unlock(&shm_ids.mutex); 566 mutex_unlock(&shm_ids(ns).mutex);
481 if(copy_to_user (buf, &shm_info, sizeof(shm_info))) { 567 if(copy_to_user (buf, &shm_info, sizeof(shm_info))) {
482 err = -EFAULT; 568 err = -EFAULT;
483 goto out; 569 goto out;
@@ -492,17 +578,17 @@ asmlinkage long sys_shmctl (int shmid, int cmd, struct shmid_ds __user *buf)
492 struct shmid64_ds tbuf; 578 struct shmid64_ds tbuf;
493 int result; 579 int result;
494 memset(&tbuf, 0, sizeof(tbuf)); 580 memset(&tbuf, 0, sizeof(tbuf));
495 shp = shm_lock(shmid); 581 shp = shm_lock(ns, shmid);
496 if(shp==NULL) { 582 if(shp==NULL) {
497 err = -EINVAL; 583 err = -EINVAL;
498 goto out; 584 goto out;
499 } else if(cmd==SHM_STAT) { 585 } else if(cmd==SHM_STAT) {
500 err = -EINVAL; 586 err = -EINVAL;
501 if (shmid > shm_ids.max_id) 587 if (shmid > shm_ids(ns).max_id)
502 goto out_unlock; 588 goto out_unlock;
503 result = shm_buildid(shmid, shp->shm_perm.seq); 589 result = shm_buildid(ns, shmid, shp->shm_perm.seq);
504 } else { 590 } else {
505 err = shm_checkid(shp,shmid); 591 err = shm_checkid(ns, shp,shmid);
506 if(err) 592 if(err)
507 goto out_unlock; 593 goto out_unlock;
508 result = 0; 594 result = 0;
@@ -534,12 +620,12 @@ asmlinkage long sys_shmctl (int shmid, int cmd, struct shmid_ds __user *buf)
534 case SHM_LOCK: 620 case SHM_LOCK:
535 case SHM_UNLOCK: 621 case SHM_UNLOCK:
536 { 622 {
537 shp = shm_lock(shmid); 623 shp = shm_lock(ns, shmid);
538 if(shp==NULL) { 624 if(shp==NULL) {
539 err = -EINVAL; 625 err = -EINVAL;
540 goto out; 626 goto out;
541 } 627 }
542 err = shm_checkid(shp,shmid); 628 err = shm_checkid(ns, shp,shmid);
543 if(err) 629 if(err)
544 goto out_unlock; 630 goto out_unlock;
545 631
@@ -590,12 +676,12 @@ asmlinkage long sys_shmctl (int shmid, int cmd, struct shmid_ds __user *buf)
590 * Instead we set a destroyed flag, and then blow 676 * Instead we set a destroyed flag, and then blow
591 * the name away when the usage hits zero. 677 * the name away when the usage hits zero.
592 */ 678 */
593 mutex_lock(&shm_ids.mutex); 679 mutex_lock(&shm_ids(ns).mutex);
594 shp = shm_lock(shmid); 680 shp = shm_lock(ns, shmid);
595 err = -EINVAL; 681 err = -EINVAL;
596 if (shp == NULL) 682 if (shp == NULL)
597 goto out_up; 683 goto out_up;
598 err = shm_checkid(shp, shmid); 684 err = shm_checkid(ns, shp, shmid);
599 if(err) 685 if(err)
600 goto out_unlock_up; 686 goto out_unlock_up;
601 687
@@ -614,14 +700,8 @@ asmlinkage long sys_shmctl (int shmid, int cmd, struct shmid_ds __user *buf)
614 if (err) 700 if (err)
615 goto out_unlock_up; 701 goto out_unlock_up;
616 702
617 if (shp->shm_nattch){ 703 do_shm_rmid(ns, shp);
618 shp->shm_perm.mode |= SHM_DEST; 704 mutex_unlock(&shm_ids(ns).mutex);
619 /* Do not find it any more */
620 shp->shm_perm.key = IPC_PRIVATE;
621 shm_unlock(shp);
622 } else
623 shm_destroy (shp);
624 mutex_unlock(&shm_ids.mutex);
625 goto out; 705 goto out;
626 } 706 }
627 707
@@ -631,12 +711,12 @@ asmlinkage long sys_shmctl (int shmid, int cmd, struct shmid_ds __user *buf)
631 err = -EFAULT; 711 err = -EFAULT;
632 goto out; 712 goto out;
633 } 713 }
634 mutex_lock(&shm_ids.mutex); 714 mutex_lock(&shm_ids(ns).mutex);
635 shp = shm_lock(shmid); 715 shp = shm_lock(ns, shmid);
636 err=-EINVAL; 716 err=-EINVAL;
637 if(shp==NULL) 717 if(shp==NULL)
638 goto out_up; 718 goto out_up;
639 err = shm_checkid(shp,shmid); 719 err = shm_checkid(ns, shp,shmid);
640 if(err) 720 if(err)
641 goto out_unlock_up; 721 goto out_unlock_up;
642 err = audit_ipc_obj(&(shp->shm_perm)); 722 err = audit_ipc_obj(&(shp->shm_perm));
@@ -673,7 +753,7 @@ asmlinkage long sys_shmctl (int shmid, int cmd, struct shmid_ds __user *buf)
673out_unlock_up: 753out_unlock_up:
674 shm_unlock(shp); 754 shm_unlock(shp);
675out_up: 755out_up:
676 mutex_unlock(&shm_ids.mutex); 756 mutex_unlock(&shm_ids(ns).mutex);
677 goto out; 757 goto out;
678out_unlock: 758out_unlock:
679 shm_unlock(shp); 759 shm_unlock(shp);
@@ -699,6 +779,7 @@ long do_shmat(int shmid, char __user *shmaddr, int shmflg, ulong *raddr)
699 unsigned long prot; 779 unsigned long prot;
700 int acc_mode; 780 int acc_mode;
701 void *user_addr; 781 void *user_addr;
782 struct ipc_namespace *ns;
702 783
703 if (shmid < 0) { 784 if (shmid < 0) {
704 err = -EINVAL; 785 err = -EINVAL;
@@ -737,12 +818,13 @@ long do_shmat(int shmid, char __user *shmaddr, int shmflg, ulong *raddr)
737 * We cannot rely on the fs check since SYSV IPC does have an 818 * We cannot rely on the fs check since SYSV IPC does have an
738 * additional creator id... 819 * additional creator id...
739 */ 820 */
740 shp = shm_lock(shmid); 821 ns = current->nsproxy->ipc_ns;
822 shp = shm_lock(ns, shmid);
741 if(shp == NULL) { 823 if(shp == NULL) {
742 err = -EINVAL; 824 err = -EINVAL;
743 goto out; 825 goto out;
744 } 826 }
745 err = shm_checkid(shp,shmid); 827 err = shm_checkid(ns, shp,shmid);
746 if (err) { 828 if (err) {
747 shm_unlock(shp); 829 shm_unlock(shp);
748 goto out; 830 goto out;
@@ -783,16 +865,16 @@ long do_shmat(int shmid, char __user *shmaddr, int shmflg, ulong *raddr)
783invalid: 865invalid:
784 up_write(&current->mm->mmap_sem); 866 up_write(&current->mm->mmap_sem);
785 867
786 mutex_lock(&shm_ids.mutex); 868 mutex_lock(&shm_ids(ns).mutex);
787 shp = shm_lock(shmid); 869 shp = shm_lock(ns, shmid);
788 BUG_ON(!shp); 870 BUG_ON(!shp);
789 shp->shm_nattch--; 871 shp->shm_nattch--;
790 if(shp->shm_nattch == 0 && 872 if(shp->shm_nattch == 0 &&
791 shp->shm_perm.mode & SHM_DEST) 873 shp->shm_perm.mode & SHM_DEST)
792 shm_destroy (shp); 874 shm_destroy(ns, shp);
793 else 875 else
794 shm_unlock(shp); 876 shm_unlock(shp);
795 mutex_unlock(&shm_ids.mutex); 877 mutex_unlock(&shm_ids(ns).mutex);
796 878
797 *raddr = (unsigned long) user_addr; 879 *raddr = (unsigned long) user_addr;
798 err = 0; 880 err = 0;