aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
Diffstat (limited to 'net')
-rw-r--r--net/ipv4/af_inet.c24
1 files changed, 21 insertions, 3 deletions
diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c
index a9e241cdc5b2..39ddb84b1b78 100644
--- a/net/ipv4/af_inet.c
+++ b/net/ipv4/af_inet.c
@@ -243,6 +243,23 @@ void build_ehash_secret(void)
243} 243}
244EXPORT_SYMBOL(build_ehash_secret); 244EXPORT_SYMBOL(build_ehash_secret);
245 245
246static inline int inet_netns_ok(struct net *net, int protocol)
247{
248 int hash;
249 struct net_protocol *ipprot;
250
251 if (net == &init_net)
252 return 1;
253
254 hash = protocol & (MAX_INET_PROTOS - 1);
255 ipprot = rcu_dereference(inet_protos[hash]);
256
257 if (ipprot == NULL)
258 /* raw IP is OK */
259 return 1;
260 return ipprot->netns_ok;
261}
262
246/* 263/*
247 * Create an inet socket. 264 * Create an inet socket.
248 */ 265 */
@@ -259,9 +276,6 @@ static int inet_create(struct net *net, struct socket *sock, int protocol)
259 int try_loading_module = 0; 276 int try_loading_module = 0;
260 int err; 277 int err;
261 278
262 if (net != &init_net)
263 return -EAFNOSUPPORT;
264
265 if (sock->type != SOCK_RAW && 279 if (sock->type != SOCK_RAW &&
266 sock->type != SOCK_DGRAM && 280 sock->type != SOCK_DGRAM &&
267 !inet_ehash_secret) 281 !inet_ehash_secret)
@@ -320,6 +334,10 @@ lookup_protocol:
320 if (answer->capability > 0 && !capable(answer->capability)) 334 if (answer->capability > 0 && !capable(answer->capability))
321 goto out_rcu_unlock; 335 goto out_rcu_unlock;
322 336
337 err = -EAFNOSUPPORT;
338 if (!inet_netns_ok(net, protocol))
339 goto out_rcu_unlock;
340
323 sock->ops = answer->ops; 341 sock->ops = answer->ops;
324 answer_prot = answer->prot; 342 answer_prot = answer->prot;
325 answer_no_check = answer->no_check; 343 answer_no_check = answer->no_check;