aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/ipc.h52
-rw-r--r--include/linux/ipc_namespace.h69
-rw-r--r--init/Kconfig7
-rw-r--r--ipc/Makefile1
-rw-r--r--ipc/ipc_sysctl.c1
-rw-r--r--ipc/msg.c3
-rw-r--r--ipc/namespace.c73
-rw-r--r--ipc/sem.c3
-rw-r--r--ipc/shm.c3
-rw-r--r--ipc/util.c61
-rw-r--r--ipc/util.h2
-rw-r--r--kernel/nsproxy.c1
12 files changed, 164 insertions, 112 deletions
diff --git a/include/linux/ipc.h b/include/linux/ipc.h
index 408696ea5189..b8826107b518 100644
--- a/include/linux/ipc.h
+++ b/include/linux/ipc.h
@@ -100,58 +100,6 @@ struct kern_ipc_perm
100 void *security; 100 void *security;
101}; 101};
102 102
103struct ipc_ids;
104struct ipc_namespace {
105 struct kref kref;
106 struct ipc_ids *ids[3];
107
108 int sem_ctls[4];
109 int used_sems;
110
111 int msg_ctlmax;
112 int msg_ctlmnb;
113 int msg_ctlmni;
114 atomic_t msg_bytes;
115 atomic_t msg_hdrs;
116
117 size_t shm_ctlmax;
118 size_t shm_ctlall;
119 int shm_ctlmni;
120 int shm_tot;
121};
122
123extern struct ipc_namespace init_ipc_ns;
124
125#ifdef CONFIG_SYSVIPC
126#define INIT_IPC_NS(ns) .ns = &init_ipc_ns,
127extern void free_ipc_ns(struct kref *kref);
128extern struct ipc_namespace *copy_ipcs(unsigned long flags,
129 struct ipc_namespace *ns);
130#else
131#define INIT_IPC_NS(ns)
132static inline struct ipc_namespace *copy_ipcs(unsigned long flags,
133 struct ipc_namespace *ns)
134{
135 return ns;
136}
137#endif
138
139static inline struct ipc_namespace *get_ipc_ns(struct ipc_namespace *ns)
140{
141#ifdef CONFIG_SYSVIPC
142 if (ns)
143 kref_get(&ns->kref);
144#endif
145 return ns;
146}
147
148static inline void put_ipc_ns(struct ipc_namespace *ns)
149{
150#ifdef CONFIG_SYSVIPC
151 kref_put(&ns->kref, free_ipc_ns);
152#endif
153}
154
155#endif /* __KERNEL__ */ 103#endif /* __KERNEL__ */
156 104
157#endif /* _LINUX_IPC_H */ 105#endif /* _LINUX_IPC_H */
diff --git a/include/linux/ipc_namespace.h b/include/linux/ipc_namespace.h
new file mode 100644
index 000000000000..a491fc9dd231
--- /dev/null
+++ b/include/linux/ipc_namespace.h
@@ -0,0 +1,69 @@
1#ifndef __IPC_NAMESPACE_H__
2#define __IPC_NAMESPACE_H__
3
4#include <linux/err.h>
5
6struct ipc_ids;
7struct ipc_namespace {
8 struct kref kref;
9 struct ipc_ids *ids[3];
10
11 int sem_ctls[4];
12 int used_sems;
13
14 int msg_ctlmax;
15 int msg_ctlmnb;
16 int msg_ctlmni;
17 atomic_t msg_bytes;
18 atomic_t msg_hdrs;
19
20 size_t shm_ctlmax;
21 size_t shm_ctlall;
22 int shm_ctlmni;
23 int shm_tot;
24};
25
26extern struct ipc_namespace init_ipc_ns;
27
28#ifdef CONFIG_SYSVIPC
29#define INIT_IPC_NS(ns) .ns = &init_ipc_ns,
30#else
31#define INIT_IPC_NS(ns)
32#endif
33
34#if defined(CONFIG_SYSVIPC) && defined(CONFIG_IPC_NS)
35extern void free_ipc_ns(struct kref *kref);
36extern struct ipc_namespace *copy_ipcs(unsigned long flags,
37 struct ipc_namespace *ns);
38
39static inline struct ipc_namespace *get_ipc_ns(struct ipc_namespace *ns)
40{
41 if (ns)
42 kref_get(&ns->kref);
43 return ns;
44}
45
46static inline void put_ipc_ns(struct ipc_namespace *ns)
47{
48 kref_put(&ns->kref, free_ipc_ns);
49}
50#else
51static inline struct ipc_namespace *copy_ipcs(unsigned long flags,
52 struct ipc_namespace *ns)
53{
54 if (flags & CLONE_NEWIPC)
55 return ERR_PTR(-EINVAL);
56
57 return ns;
58}
59
60static inline struct ipc_namespace *get_ipc_ns(struct ipc_namespace *ns)
61{
62 return ns;
63}
64
65static inline void put_ipc_ns(struct ipc_namespace *ns)
66{
67}
68#endif
69#endif
diff --git a/init/Kconfig b/init/Kconfig
index fef641af78c2..47879a874966 100644
--- a/init/Kconfig
+++ b/init/Kconfig
@@ -436,6 +436,13 @@ config UTS_NS
436 In this namespace tasks see different info provided with the 436 In this namespace tasks see different info provided with the
437 uname() system call 437 uname() system call
438 438
439config IPC_NS
440 bool "IPC namespace"
441 depends on NAMESPACES && SYSVIPC
442 help
443 In this namespace tasks work with IPC ids which correspond to
444 different IPC objects in different namespaces
445
439config BLK_DEV_INITRD 446config BLK_DEV_INITRD
440 bool "Initial RAM filesystem and RAM disk (initramfs/initrd) support" 447 bool "Initial RAM filesystem and RAM disk (initramfs/initrd) support"
441 depends on BROKEN || !FRV 448 depends on BROKEN || !FRV
diff --git a/ipc/Makefile b/ipc/Makefile
index b93bba6652f1..5fc5e33ea047 100644
--- a/ipc/Makefile
+++ b/ipc/Makefile
@@ -7,4 +7,5 @@ obj-$(CONFIG_SYSVIPC) += util.o msgutil.o msg.o sem.o shm.o
7obj-$(CONFIG_SYSVIPC_SYSCTL) += ipc_sysctl.o 7obj-$(CONFIG_SYSVIPC_SYSCTL) += ipc_sysctl.o
8obj_mq-$(CONFIG_COMPAT) += compat_mq.o 8obj_mq-$(CONFIG_COMPAT) += compat_mq.o
9obj-$(CONFIG_POSIX_MQUEUE) += mqueue.o msgutil.o $(obj_mq-y) 9obj-$(CONFIG_POSIX_MQUEUE) += mqueue.o msgutil.o $(obj_mq-y)
10obj-$(CONFIG_IPC_NS) += namespace.o
10 11
diff --git a/ipc/ipc_sysctl.c b/ipc/ipc_sysctl.c
index 79e24e878c1e..7f4235bed51b 100644
--- a/ipc/ipc_sysctl.c
+++ b/ipc/ipc_sysctl.c
@@ -14,6 +14,7 @@
14#include <linux/nsproxy.h> 14#include <linux/nsproxy.h>
15#include <linux/sysctl.h> 15#include <linux/sysctl.h>
16#include <linux/uaccess.h> 16#include <linux/uaccess.h>
17#include <linux/ipc_namespace.h>
17 18
18static void *get_ipc(ctl_table *table) 19static void *get_ipc(ctl_table *table)
19{ 20{
diff --git a/ipc/msg.c b/ipc/msg.c
index ec0c724054b9..5879bfeb79ca 100644
--- a/ipc/msg.c
+++ b/ipc/msg.c
@@ -36,6 +36,7 @@
36#include <linux/seq_file.h> 36#include <linux/seq_file.h>
37#include <linux/rwsem.h> 37#include <linux/rwsem.h>
38#include <linux/nsproxy.h> 38#include <linux/nsproxy.h>
39#include <linux/ipc_namespace.h>
39 40
40#include <asm/current.h> 41#include <asm/current.h>
41#include <asm/uaccess.h> 42#include <asm/uaccess.h>
@@ -90,6 +91,7 @@ static void __msg_init_ns(struct ipc_namespace *ns, struct ipc_ids *ids)
90 ipc_init_ids(ids); 91 ipc_init_ids(ids);
91} 92}
92 93
94#ifdef CONFIG_IPC_NS
93int msg_init_ns(struct ipc_namespace *ns) 95int msg_init_ns(struct ipc_namespace *ns)
94{ 96{
95 struct ipc_ids *ids; 97 struct ipc_ids *ids;
@@ -128,6 +130,7 @@ void msg_exit_ns(struct ipc_namespace *ns)
128 kfree(ns->ids[IPC_MSG_IDS]); 130 kfree(ns->ids[IPC_MSG_IDS]);
129 ns->ids[IPC_MSG_IDS] = NULL; 131 ns->ids[IPC_MSG_IDS] = NULL;
130} 132}
133#endif
131 134
132void __init msg_init(void) 135void __init msg_init(void)
133{ 136{
diff --git a/ipc/namespace.c b/ipc/namespace.c
new file mode 100644
index 000000000000..cef1139e6c96
--- /dev/null
+++ b/ipc/namespace.c
@@ -0,0 +1,73 @@
1/*
2 * linux/ipc/namespace.c
3 * Copyright (C) 2006 Pavel Emelyanov <xemul@openvz.org> OpenVZ, SWsoft Inc.
4 */
5
6#include <linux/ipc.h>
7#include <linux/msg.h>
8#include <linux/ipc_namespace.h>
9#include <linux/rcupdate.h>
10#include <linux/nsproxy.h>
11#include <linux/slab.h>
12
13#include "util.h"
14
15static struct ipc_namespace *clone_ipc_ns(struct ipc_namespace *old_ns)
16{
17 int err;
18 struct ipc_namespace *ns;
19
20 err = -ENOMEM;
21 ns = kmalloc(sizeof(struct ipc_namespace), GFP_KERNEL);
22 if (ns == NULL)
23 goto err_mem;
24
25 err = sem_init_ns(ns);
26 if (err)
27 goto err_sem;
28 err = msg_init_ns(ns);
29 if (err)
30 goto err_msg;
31 err = shm_init_ns(ns);
32 if (err)
33 goto err_shm;
34
35 kref_init(&ns->kref);
36 return ns;
37
38err_shm:
39 msg_exit_ns(ns);
40err_msg:
41 sem_exit_ns(ns);
42err_sem:
43 kfree(ns);
44err_mem:
45 return ERR_PTR(err);
46}
47
48struct ipc_namespace *copy_ipcs(unsigned long flags, struct ipc_namespace *ns)
49{
50 struct ipc_namespace *new_ns;
51
52 BUG_ON(!ns);
53 get_ipc_ns(ns);
54
55 if (!(flags & CLONE_NEWIPC))
56 return ns;
57
58 new_ns = clone_ipc_ns(ns);
59
60 put_ipc_ns(ns);
61 return new_ns;
62}
63
64void free_ipc_ns(struct kref *kref)
65{
66 struct ipc_namespace *ns;
67
68 ns = container_of(kref, struct ipc_namespace, kref);
69 sem_exit_ns(ns);
70 msg_exit_ns(ns);
71 shm_exit_ns(ns);
72 kfree(ns);
73}
diff --git a/ipc/sem.c b/ipc/sem.c
index d65e285b7e30..84c701fe5004 100644
--- a/ipc/sem.c
+++ b/ipc/sem.c
@@ -82,6 +82,7 @@
82#include <linux/seq_file.h> 82#include <linux/seq_file.h>
83#include <linux/rwsem.h> 83#include <linux/rwsem.h>
84#include <linux/nsproxy.h> 84#include <linux/nsproxy.h>
85#include <linux/ipc_namespace.h>
85 86
86#include <asm/uaccess.h> 87#include <asm/uaccess.h>
87#include "util.h" 88#include "util.h"
@@ -128,6 +129,7 @@ static void __sem_init_ns(struct ipc_namespace *ns, struct ipc_ids *ids)
128 ipc_init_ids(ids); 129 ipc_init_ids(ids);
129} 130}
130 131
132#ifdef CONFIG_IPC_NS
131int sem_init_ns(struct ipc_namespace *ns) 133int sem_init_ns(struct ipc_namespace *ns)
132{ 134{
133 struct ipc_ids *ids; 135 struct ipc_ids *ids;
@@ -165,6 +167,7 @@ void sem_exit_ns(struct ipc_namespace *ns)
165 kfree(ns->ids[IPC_SEM_IDS]); 167 kfree(ns->ids[IPC_SEM_IDS]);
166 ns->ids[IPC_SEM_IDS] = NULL; 168 ns->ids[IPC_SEM_IDS] = NULL;
167} 169}
170#endif
168 171
169void __init sem_init (void) 172void __init sem_init (void)
170{ 173{
diff --git a/ipc/shm.c b/ipc/shm.c
index 65c3a294aba5..07f4b7abc80a 100644
--- a/ipc/shm.c
+++ b/ipc/shm.c
@@ -38,6 +38,7 @@
38#include <linux/rwsem.h> 38#include <linux/rwsem.h>
39#include <linux/nsproxy.h> 39#include <linux/nsproxy.h>
40#include <linux/mount.h> 40#include <linux/mount.h>
41#include <linux/ipc_namespace.h>
41 42
42#include <asm/uaccess.h> 43#include <asm/uaccess.h>
43 44
@@ -96,6 +97,7 @@ static void do_shm_rmid(struct ipc_namespace *ns, struct shmid_kernel *shp)
96 shm_destroy(ns, shp); 97 shm_destroy(ns, shp);
97} 98}
98 99
100#ifdef CONFIG_IPC_NS
99int shm_init_ns(struct ipc_namespace *ns) 101int shm_init_ns(struct ipc_namespace *ns)
100{ 102{
101 struct ipc_ids *ids; 103 struct ipc_ids *ids;
@@ -133,6 +135,7 @@ void shm_exit_ns(struct ipc_namespace *ns)
133 kfree(ns->ids[IPC_SHM_IDS]); 135 kfree(ns->ids[IPC_SHM_IDS]);
134 ns->ids[IPC_SHM_IDS] = NULL; 136 ns->ids[IPC_SHM_IDS] = NULL;
135} 137}
138#endif
136 139
137void __init shm_init (void) 140void __init shm_init (void)
138{ 141{
diff --git a/ipc/util.c b/ipc/util.c
index 76c1f3461e22..5432b8e34c9b 100644
--- a/ipc/util.c
+++ b/ipc/util.c
@@ -33,6 +33,7 @@
33#include <linux/audit.h> 33#include <linux/audit.h>
34#include <linux/nsproxy.h> 34#include <linux/nsproxy.h>
35#include <linux/rwsem.h> 35#include <linux/rwsem.h>
36#include <linux/ipc_namespace.h>
36 37
37#include <asm/unistd.h> 38#include <asm/unistd.h>
38 39
@@ -51,66 +52,6 @@ struct ipc_namespace init_ipc_ns = {
51 }, 52 },
52}; 53};
53 54
54static struct ipc_namespace *clone_ipc_ns(struct ipc_namespace *old_ns)
55{
56 int err;
57 struct ipc_namespace *ns;
58
59 err = -ENOMEM;
60 ns = kmalloc(sizeof(struct ipc_namespace), GFP_KERNEL);
61 if (ns == NULL)
62 goto err_mem;
63
64 err = sem_init_ns(ns);
65 if (err)
66 goto err_sem;
67 err = msg_init_ns(ns);
68 if (err)
69 goto err_msg;
70 err = shm_init_ns(ns);
71 if (err)
72 goto err_shm;
73
74 kref_init(&ns->kref);
75 return ns;
76
77err_shm:
78 msg_exit_ns(ns);
79err_msg:
80 sem_exit_ns(ns);
81err_sem:
82 kfree(ns);
83err_mem:
84 return ERR_PTR(err);
85}
86
87struct ipc_namespace *copy_ipcs(unsigned long flags, struct ipc_namespace *ns)
88{
89 struct ipc_namespace *new_ns;
90
91 BUG_ON(!ns);
92 get_ipc_ns(ns);
93
94 if (!(flags & CLONE_NEWIPC))
95 return ns;
96
97 new_ns = clone_ipc_ns(ns);
98
99 put_ipc_ns(ns);
100 return new_ns;
101}
102
103void free_ipc_ns(struct kref *kref)
104{
105 struct ipc_namespace *ns;
106
107 ns = container_of(kref, struct ipc_namespace, kref);
108 sem_exit_ns(ns);
109 msg_exit_ns(ns);
110 shm_exit_ns(ns);
111 kfree(ns);
112}
113
114/** 55/**
115 * ipc_init - initialise IPC subsystem 56 * ipc_init - initialise IPC subsystem
116 * 57 *
diff --git a/ipc/util.h b/ipc/util.h
index 9ffea40457ce..fc6b7294f764 100644
--- a/ipc/util.h
+++ b/ipc/util.h
@@ -20,6 +20,8 @@ void sem_init (void);
20void msg_init (void); 20void msg_init (void);
21void shm_init (void); 21void shm_init (void);
22 22
23struct ipc_namespace;
24
23int sem_init_ns(struct ipc_namespace *ns); 25int sem_init_ns(struct ipc_namespace *ns);
24int msg_init_ns(struct ipc_namespace *ns); 26int msg_init_ns(struct ipc_namespace *ns);
25int shm_init_ns(struct ipc_namespace *ns); 27int shm_init_ns(struct ipc_namespace *ns);
diff --git a/kernel/nsproxy.c b/kernel/nsproxy.c
index 79f871bc0ef4..f5d332cf8c63 100644
--- a/kernel/nsproxy.c
+++ b/kernel/nsproxy.c
@@ -21,6 +21,7 @@
21#include <linux/utsname.h> 21#include <linux/utsname.h>
22#include <linux/pid_namespace.h> 22#include <linux/pid_namespace.h>
23#include <net/net_namespace.h> 23#include <net/net_namespace.h>
24#include <linux/ipc_namespace.h>
24 25
25static struct kmem_cache *nsproxy_cachep; 26static struct kmem_cache *nsproxy_cachep;
26 27