diff options
Diffstat (limited to 'net')
-rw-r--r-- | net/ipv4/af_inet.c | 24 |
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 | } |
244 | EXPORT_SYMBOL(build_ehash_secret); | 244 | EXPORT_SYMBOL(build_ehash_secret); |
245 | 245 | ||
246 | static 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; |