1b1d3c31fb01e8afddf4a7439e19fd6d566b5db2
[linux-2.6.git] / linux-2.6-760-unshare-netns-fix.patch
1 diff -Nurb linux-2.6.22-600/kernel/fork.c linux-2.6.22-601/kernel/fork.c
2 --- linux-2.6.22-600/kernel/fork.c      2008-03-28 11:22:20.000000000 -0600
3 +++ linux-2.6.22-601/kernel/fork.c      2008-03-28 11:22:25.000000000 -0600
4 @@ -1673,7 +1673,7 @@
5         /* Return -EINVAL for all unsupported flags */
6         err = -EINVAL;
7         if (unshare_flags & ~(CLONE_THREAD|CLONE_FS|CLONE_NEWNS|CLONE_SIGHAND|
8 -                               CLONE_VM|CLONE_FILES|CLONE_SYSVSEM|
9 +                               CLONE_VM|CLONE_FILES|CLONE_SYSVSEM|CLONE_NEWNET|
10                                 CLONE_NEWUTS|CLONE_NEWIPC|CLONE_NEWUSER))
11                 goto bad_unshare_out;
12  
13 diff -Nurb linux-2.6.22-600/kernel/nsproxy.c linux-2.6.22-601/kernel/nsproxy.c
14 --- linux-2.6.22-600/kernel/nsproxy.c   2008-03-28 11:22:23.000000000 -0600
15 +++ linux-2.6.22-601/kernel/nsproxy.c   2008-03-28 11:22:25.000000000 -0600
16 @@ -91,12 +91,14 @@
17  {
18         struct nsproxy *ns;
19  
20 -       ns = kmemdup(orig, sizeof(struct nsproxy), GFP_KERNEL);
21 -       if (ns)
22 +       ns = kmem_cache_alloc(nsproxy_cachep, GFP_KERNEL);
23 +       if (ns) {
24 +               memcpy(ns, orig, sizeof(struct nsproxy));
25                 atomic_set(&ns->count, 1);
26         vxdprintk(VXD_CBIT(space, 2), "clone_nsproxy(%p[%u] = %p[1]",
27                 orig, atomic_read(&orig->count), ns);
28         atomic_inc(&vs_global_nsproxy);
29 +       }
30         return ns;
31  }
32  
33 @@ -120,36 +122,46 @@
34                 return ERR_PTR(-ENOMEM);
35  
36         new_nsp->mnt_ns = copy_mnt_ns(flags, orig->mnt_ns, new_fs);
37 -       if (IS_ERR(new_nsp->mnt_ns))
38 +       if (IS_ERR(new_nsp->mnt_ns)) {
39 +               err = PTR_ERR(new_nsp->mnt_ns);
40                 goto out_ns;
41 +       }
42  
43         new_nsp->uts_ns = copy_utsname(flags, orig->uts_ns);
44 -       if (IS_ERR(new_nsp->uts_ns))
45 +       if (IS_ERR(new_nsp->uts_ns)) {
46 +               err = PTR_ERR(new_nsp->uts_ns);
47                 goto out_uts;
48 +       }
49  
50         new_nsp->ipc_ns = copy_ipcs(flags, orig->ipc_ns);
51 -       if (IS_ERR(new_nsp->ipc_ns))
52 +       if (IS_ERR(new_nsp->ipc_ns)) {
53 +               err = PTR_ERR(new_nsp->ipc_ns);
54                 goto out_ipc;
55 +       }
56  
57         new_nsp->pid_ns = copy_pid_ns(flags, orig->pid_ns);
58 -       if (IS_ERR(new_nsp->pid_ns))
59 +       if (IS_ERR(new_nsp->pid_ns)) {
60 +               err = PTR_ERR(new_nsp->pid_ns);
61                 goto out_pid;
62 +       }
63  
64         new_nsp->user_ns = copy_user_ns(flags, orig->user_ns);
65 -       if (IS_ERR(new_nsp->user_ns))
66 +       if (IS_ERR(new_nsp->user_ns)) {
67 +               err = PTR_ERR(new_nsp->user_ns);
68                 goto out_user;
69 +       }
70  
71         new_nsp->net_ns = copy_net_ns(flags, orig->net_ns);
72 -       if (IS_ERR(new_nsp->net_ns))
73 +       if (IS_ERR(new_nsp->net_ns)) {
74 +               err = PTR_ERR(new_nsp->net_ns);
75                 goto out_net;
76 +       }
77  
78         return new_nsp;
79  
80  out_net:
81         if (new_nsp->user_ns)
82                 put_user_ns(new_nsp->user_ns);
83 -       if (new_nsp->net_ns)
84 -               put_net(new_nsp->net_ns);
85  out_user:
86         if (new_nsp->pid_ns)
87                 put_pid_ns(new_nsp->pid_ns);
88 @@ -190,6 +202,8 @@
89                         get_ipc_ns(ns->ipc_ns);
90                 if (ns->pid_ns)
91                         get_pid_ns(ns->pid_ns);
92 +               if (ns->net_ns)
93 +                       get_net(ns->net_ns);
94         }
95         return ns;
96  }
97 @@ -258,8 +272,10 @@
98                 put_ipc_ns(ns->ipc_ns);
99         if (ns->pid_ns)
100                 put_pid_ns(ns->pid_ns);
101 +       if (ns->net_ns)
102 +               put_net(ns->net_ns);
103         atomic_dec(&vs_global_nsproxy);
104 -       kfree(ns);
105 +       kmem_cache_free(nsproxy_cachep, ns);
106  }
107  
108  /*
109 diff -Nurb linux-2.6.22-600/kernel/vserver/space.c linux-2.6.22-601/kernel/vserver/space.c
110 --- linux-2.6.22-600/kernel/vserver/space.c     2008-03-28 11:22:23.000000000 -0600
111 +++ linux-2.6.22-601/kernel/vserver/space.c     2008-03-28 11:22:25.000000000 -0600
112 @@ -15,6 +15,7 @@
113  #include <linux/utsname.h>
114  #include <linux/nsproxy.h>
115  #include <linux/err.h>
116 +#include <net/net_namespace.h>
117  #include <asm/uaccess.h>
118  
119  #include <linux/vs_context.h>
120 @@ -55,6 +56,7 @@
121         struct mnt_namespace *old_ns;
122         struct uts_namespace *old_uts;
123         struct ipc_namespace *old_ipc;
124 +       struct net *old_net;
125         struct nsproxy *nsproxy;
126  
127         nsproxy = copy_nsproxy(old_nsproxy);
128 @@ -85,12 +87,26 @@
129         } else
130                 old_ipc = NULL;
131  
132 +       if (mask & CLONE_NEWNET) {
133 +               old_net = nsproxy->net_ns;
134 +               nsproxy->net_ns = new_nsproxy->net_ns;
135 +               if (nsproxy->net_ns) {
136 +                       get_net(nsproxy->net_ns);
137 +                       printk(KERN_ALERT "Cloning network namespace\n"); 
138 +               }       
139 +       } else
140 +               old_net = NULL;
141 +
142 +
143         if (old_ns)
144                 put_mnt_ns(old_ns);
145         if (old_uts)
146                 put_uts_ns(old_uts);
147         if (old_ipc)
148                 put_ipc_ns(old_ipc);
149 +       if (old_net)
150 +               put_net(old_net);
151 +
152  out:
153         return nsproxy;
154  }
155 --- kernel/vserver/space.c.orig 2008-10-10 11:37:58.000000000 -0400
156 +++ kernel/vserver/space.c      2008-10-20 13:36:17.000000000 -0400
157 @@ -91,7 +91,7 @@
158                 nsproxy->net_ns = new_nsproxy->net_ns;
159                 if (nsproxy->net_ns) {
160                         get_net(nsproxy->net_ns);
161 -                       printk(KERN_ALERT "Cloning network namespace\n"); 
162 +                   printk(KERN_ALERT "Cloning network namespace\n"); 
163                 }       
164         } else
165                 old_net = NULL;
166 @@ -168,9 +168,6 @@
167         if (!mask)
168                 mask = vxi->vx_nsmask;
169  
170 -       if ((mask & vxi->vx_nsmask) != mask)
171 -               return -EINVAL;
172 -
173         proxy = vxi->vx_nsproxy;
174         fs = vxi->vx_fs;
175  
176 @@ -220,9 +217,6 @@
177         if (!mask)
178                 mask = space_mask.mask;
179  
180 -       if ((mask & space_mask.mask) != mask)
181 -               return -EINVAL;
182 -
183         proxy_vxi = vxi->vx_nsproxy;
184         fs_vxi = vxi->vx_fs;
185