diff options
author | David S. Miller <davem@davemloft.net> | 2015-11-08 20:56:39 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2015-11-08 20:56:39 -0500 |
commit | b73c8bfd07eb53a964b7b917b0599e12103097fb (patch) | |
tree | 584b8fc12bc6ef6c53c676572594eb4ef67f4a29 | |
parent | fb9a10d9d8552acf6f9dee2ecb2d047777821d8b (diff) | |
parent | 3aed822591556f93169ff532fda8c71b9b596de5 (diff) |
Merge branch 'skb_to_full_sk'
Eric Dumazet says:
====================
net: add skb_to_full_sk() helper
Many contexts need to reach listener socket from skb attached
to a request socket. This patch series add skb_to_full_sk() to
clearly express this need and use it where appropriate.
====================
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | include/net/inet_sock.h | 12 | ||||
-rw-r--r-- | net/netfilter/nft_meta.c | 36 | ||||
-rw-r--r-- | net/netfilter/xt_owner.c | 6 | ||||
-rw-r--r-- | net/sched/cls_flow.c | 15 | ||||
-rw-r--r-- | net/sched/em_meta.c | 138 | ||||
-rw-r--r-- | security/selinux/hooks.c | 16 | ||||
-rw-r--r-- | security/selinux/netlabel.c | 2 | ||||
-rw-r--r-- | security/smack/smack_netfilter.c | 11 |
8 files changed, 149 insertions, 87 deletions
diff --git a/include/net/inet_sock.h b/include/net/inet_sock.h index f5bf7310e334..2134e6d815bc 100644 --- a/include/net/inet_sock.h +++ b/include/net/inet_sock.h | |||
@@ -210,6 +210,18 @@ struct inet_sock { | |||
210 | #define IP_CMSG_ORIGDSTADDR BIT(6) | 210 | #define IP_CMSG_ORIGDSTADDR BIT(6) |
211 | #define IP_CMSG_CHECKSUM BIT(7) | 211 | #define IP_CMSG_CHECKSUM BIT(7) |
212 | 212 | ||
213 | /* SYNACK messages might be attached to request sockets. | ||
214 | * Some places want to reach the listener in this case. | ||
215 | */ | ||
216 | static inline struct sock *skb_to_full_sk(const struct sk_buff *skb) | ||
217 | { | ||
218 | struct sock *sk = skb->sk; | ||
219 | |||
220 | if (sk && sk->sk_state == TCP_NEW_SYN_RECV) | ||
221 | sk = inet_reqsk(sk)->rsk_listener; | ||
222 | return sk; | ||
223 | } | ||
224 | |||
213 | static inline struct inet_sock *inet_sk(const struct sock *sk) | 225 | static inline struct inet_sock *inet_sk(const struct sock *sk) |
214 | { | 226 | { |
215 | return (struct inet_sock *)sk; | 227 | return (struct inet_sock *)sk; |
diff --git a/net/netfilter/nft_meta.c b/net/netfilter/nft_meta.c index e4ad2c24bc41..9dfaf4d55ee0 100644 --- a/net/netfilter/nft_meta.c +++ b/net/netfilter/nft_meta.c | |||
@@ -31,6 +31,7 @@ void nft_meta_get_eval(const struct nft_expr *expr, | |||
31 | const struct nft_meta *priv = nft_expr_priv(expr); | 31 | const struct nft_meta *priv = nft_expr_priv(expr); |
32 | const struct sk_buff *skb = pkt->skb; | 32 | const struct sk_buff *skb = pkt->skb; |
33 | const struct net_device *in = pkt->in, *out = pkt->out; | 33 | const struct net_device *in = pkt->in, *out = pkt->out; |
34 | struct sock *sk; | ||
34 | u32 *dest = ®s->data[priv->dreg]; | 35 | u32 *dest = ®s->data[priv->dreg]; |
35 | 36 | ||
36 | switch (priv->key) { | 37 | switch (priv->key) { |
@@ -86,33 +87,35 @@ void nft_meta_get_eval(const struct nft_expr *expr, | |||
86 | *(u16 *)dest = out->type; | 87 | *(u16 *)dest = out->type; |
87 | break; | 88 | break; |
88 | case NFT_META_SKUID: | 89 | case NFT_META_SKUID: |
89 | if (skb->sk == NULL || !sk_fullsock(skb->sk)) | 90 | sk = skb_to_full_sk(skb); |
91 | if (!sk || !sk_fullsock(sk)) | ||
90 | goto err; | 92 | goto err; |
91 | 93 | ||
92 | read_lock_bh(&skb->sk->sk_callback_lock); | 94 | read_lock_bh(&sk->sk_callback_lock); |
93 | if (skb->sk->sk_socket == NULL || | 95 | if (sk->sk_socket == NULL || |
94 | skb->sk->sk_socket->file == NULL) { | 96 | sk->sk_socket->file == NULL) { |
95 | read_unlock_bh(&skb->sk->sk_callback_lock); | 97 | read_unlock_bh(&sk->sk_callback_lock); |
96 | goto err; | 98 | goto err; |
97 | } | 99 | } |
98 | 100 | ||
99 | *dest = from_kuid_munged(&init_user_ns, | 101 | *dest = from_kuid_munged(&init_user_ns, |
100 | skb->sk->sk_socket->file->f_cred->fsuid); | 102 | sk->sk_socket->file->f_cred->fsuid); |
101 | read_unlock_bh(&skb->sk->sk_callback_lock); | 103 | read_unlock_bh(&sk->sk_callback_lock); |
102 | break; | 104 | break; |
103 | case NFT_META_SKGID: | 105 | case NFT_META_SKGID: |
104 | if (skb->sk == NULL || !sk_fullsock(skb->sk)) | 106 | sk = skb_to_full_sk(skb); |
107 | if (!sk || !sk_fullsock(sk)) | ||
105 | goto err; | 108 | goto err; |
106 | 109 | ||
107 | read_lock_bh(&skb->sk->sk_callback_lock); | 110 | read_lock_bh(&sk->sk_callback_lock); |
108 | if (skb->sk->sk_socket == NULL || | 111 | if (sk->sk_socket == NULL || |
109 | skb->sk->sk_socket->file == NULL) { | 112 | sk->sk_socket->file == NULL) { |
110 | read_unlock_bh(&skb->sk->sk_callback_lock); | 113 | read_unlock_bh(&sk->sk_callback_lock); |
111 | goto err; | 114 | goto err; |
112 | } | 115 | } |
113 | *dest = from_kgid_munged(&init_user_ns, | 116 | *dest = from_kgid_munged(&init_user_ns, |
114 | skb->sk->sk_socket->file->f_cred->fsgid); | 117 | sk->sk_socket->file->f_cred->fsgid); |
115 | read_unlock_bh(&skb->sk->sk_callback_lock); | 118 | read_unlock_bh(&sk->sk_callback_lock); |
116 | break; | 119 | break; |
117 | #ifdef CONFIG_IP_ROUTE_CLASSID | 120 | #ifdef CONFIG_IP_ROUTE_CLASSID |
118 | case NFT_META_RTCLASSID: { | 121 | case NFT_META_RTCLASSID: { |
@@ -168,9 +171,10 @@ void nft_meta_get_eval(const struct nft_expr *expr, | |||
168 | break; | 171 | break; |
169 | #ifdef CONFIG_CGROUP_NET_CLASSID | 172 | #ifdef CONFIG_CGROUP_NET_CLASSID |
170 | case NFT_META_CGROUP: | 173 | case NFT_META_CGROUP: |
171 | if (skb->sk == NULL || !sk_fullsock(skb->sk)) | 174 | sk = skb_to_full_sk(skb); |
175 | if (!sk || !sk_fullsock(sk)) | ||
172 | goto err; | 176 | goto err; |
173 | *dest = skb->sk->sk_classid; | 177 | *dest = sk->sk_classid; |
174 | break; | 178 | break; |
175 | #endif | 179 | #endif |
176 | default: | 180 | default: |
diff --git a/net/netfilter/xt_owner.c b/net/netfilter/xt_owner.c index ca2e577ed8ac..1302b475abcb 100644 --- a/net/netfilter/xt_owner.c +++ b/net/netfilter/xt_owner.c | |||
@@ -14,6 +14,7 @@ | |||
14 | #include <linux/skbuff.h> | 14 | #include <linux/skbuff.h> |
15 | #include <linux/file.h> | 15 | #include <linux/file.h> |
16 | #include <net/sock.h> | 16 | #include <net/sock.h> |
17 | #include <net/inet_sock.h> | ||
17 | #include <linux/netfilter/x_tables.h> | 18 | #include <linux/netfilter/x_tables.h> |
18 | #include <linux/netfilter/xt_owner.h> | 19 | #include <linux/netfilter/xt_owner.h> |
19 | 20 | ||
@@ -33,8 +34,9 @@ owner_mt(const struct sk_buff *skb, struct xt_action_param *par) | |||
33 | { | 34 | { |
34 | const struct xt_owner_match_info *info = par->matchinfo; | 35 | const struct xt_owner_match_info *info = par->matchinfo; |
35 | const struct file *filp; | 36 | const struct file *filp; |
37 | struct sock *sk = skb_to_full_sk(skb); | ||
36 | 38 | ||
37 | if (skb->sk == NULL || skb->sk->sk_socket == NULL) | 39 | if (sk == NULL || sk->sk_socket == NULL) |
38 | return (info->match ^ info->invert) == 0; | 40 | return (info->match ^ info->invert) == 0; |
39 | else if (info->match & info->invert & XT_OWNER_SOCKET) | 41 | else if (info->match & info->invert & XT_OWNER_SOCKET) |
40 | /* | 42 | /* |
@@ -43,7 +45,7 @@ owner_mt(const struct sk_buff *skb, struct xt_action_param *par) | |||
43 | */ | 45 | */ |
44 | return false; | 46 | return false; |
45 | 47 | ||
46 | filp = skb->sk->sk_socket->file; | 48 | filp = sk->sk_socket->file; |
47 | if (filp == NULL) | 49 | if (filp == NULL) |
48 | return ((info->match ^ info->invert) & | 50 | return ((info->match ^ info->invert) & |
49 | (XT_OWNER_UID | XT_OWNER_GID)) == 0; | 51 | (XT_OWNER_UID | XT_OWNER_GID)) == 0; |
diff --git a/net/sched/cls_flow.c b/net/sched/cls_flow.c index 536838b657bf..fbfec6a18839 100644 --- a/net/sched/cls_flow.c +++ b/net/sched/cls_flow.c | |||
@@ -22,6 +22,7 @@ | |||
22 | #include <linux/if_vlan.h> | 22 | #include <linux/if_vlan.h> |
23 | #include <linux/slab.h> | 23 | #include <linux/slab.h> |
24 | #include <linux/module.h> | 24 | #include <linux/module.h> |
25 | #include <net/inet_sock.h> | ||
25 | 26 | ||
26 | #include <net/pkt_cls.h> | 27 | #include <net/pkt_cls.h> |
27 | #include <net/ip.h> | 28 | #include <net/ip.h> |
@@ -197,8 +198,11 @@ static u32 flow_get_rtclassid(const struct sk_buff *skb) | |||
197 | 198 | ||
198 | static u32 flow_get_skuid(const struct sk_buff *skb) | 199 | static u32 flow_get_skuid(const struct sk_buff *skb) |
199 | { | 200 | { |
200 | if (skb->sk && skb->sk->sk_socket && skb->sk->sk_socket->file) { | 201 | struct sock *sk = skb_to_full_sk(skb); |
201 | kuid_t skuid = skb->sk->sk_socket->file->f_cred->fsuid; | 202 | |
203 | if (sk && sk->sk_socket && sk->sk_socket->file) { | ||
204 | kuid_t skuid = sk->sk_socket->file->f_cred->fsuid; | ||
205 | |||
202 | return from_kuid(&init_user_ns, skuid); | 206 | return from_kuid(&init_user_ns, skuid); |
203 | } | 207 | } |
204 | return 0; | 208 | return 0; |
@@ -206,8 +210,11 @@ static u32 flow_get_skuid(const struct sk_buff *skb) | |||
206 | 210 | ||
207 | static u32 flow_get_skgid(const struct sk_buff *skb) | 211 | static u32 flow_get_skgid(const struct sk_buff *skb) |
208 | { | 212 | { |
209 | if (skb->sk && skb->sk->sk_socket && skb->sk->sk_socket->file) { | 213 | struct sock *sk = skb_to_full_sk(skb); |
210 | kgid_t skgid = skb->sk->sk_socket->file->f_cred->fsgid; | 214 | |
215 | if (sk && sk->sk_socket && sk->sk_socket->file) { | ||
216 | kgid_t skgid = sk->sk_socket->file->f_cred->fsgid; | ||
217 | |||
211 | return from_kgid(&init_user_ns, skgid); | 218 | return from_kgid(&init_user_ns, skgid); |
212 | } | 219 | } |
213 | return 0; | 220 | return 0; |
diff --git a/net/sched/em_meta.c b/net/sched/em_meta.c index b5294ce20cd4..f2aabc0089da 100644 --- a/net/sched/em_meta.c +++ b/net/sched/em_meta.c | |||
@@ -343,119 +343,145 @@ META_COLLECTOR(int_sk_refcnt) | |||
343 | 343 | ||
344 | META_COLLECTOR(int_sk_rcvbuf) | 344 | META_COLLECTOR(int_sk_rcvbuf) |
345 | { | 345 | { |
346 | if (skip_nonlocal(skb)) { | 346 | const struct sock *sk = skb_to_full_sk(skb); |
347 | |||
348 | if (!sk) { | ||
347 | *err = -1; | 349 | *err = -1; |
348 | return; | 350 | return; |
349 | } | 351 | } |
350 | dst->value = skb->sk->sk_rcvbuf; | 352 | dst->value = sk->sk_rcvbuf; |
351 | } | 353 | } |
352 | 354 | ||
353 | META_COLLECTOR(int_sk_shutdown) | 355 | META_COLLECTOR(int_sk_shutdown) |
354 | { | 356 | { |
355 | if (skip_nonlocal(skb)) { | 357 | const struct sock *sk = skb_to_full_sk(skb); |
358 | |||
359 | if (!sk) { | ||
356 | *err = -1; | 360 | *err = -1; |
357 | return; | 361 | return; |
358 | } | 362 | } |
359 | dst->value = skb->sk->sk_shutdown; | 363 | dst->value = sk->sk_shutdown; |
360 | } | 364 | } |
361 | 365 | ||
362 | META_COLLECTOR(int_sk_proto) | 366 | META_COLLECTOR(int_sk_proto) |
363 | { | 367 | { |
364 | if (skip_nonlocal(skb)) { | 368 | const struct sock *sk = skb_to_full_sk(skb); |
369 | |||
370 | if (!sk) { | ||
365 | *err = -1; | 371 | *err = -1; |
366 | return; | 372 | return; |
367 | } | 373 | } |
368 | dst->value = skb->sk->sk_protocol; | 374 | dst->value = sk->sk_protocol; |
369 | } | 375 | } |
370 | 376 | ||
371 | META_COLLECTOR(int_sk_type) | 377 | META_COLLECTOR(int_sk_type) |
372 | { | 378 | { |
373 | if (skip_nonlocal(skb)) { | 379 | const struct sock *sk = skb_to_full_sk(skb); |
380 | |||
381 | if (!sk) { | ||
374 | *err = -1; | 382 | *err = -1; |
375 | return; | 383 | return; |
376 | } | 384 | } |
377 | dst->value = skb->sk->sk_type; | 385 | dst->value = sk->sk_type; |
378 | } | 386 | } |
379 | 387 | ||
380 | META_COLLECTOR(int_sk_rmem_alloc) | 388 | META_COLLECTOR(int_sk_rmem_alloc) |
381 | { | 389 | { |
382 | if (skip_nonlocal(skb)) { | 390 | const struct sock *sk = skb_to_full_sk(skb); |
391 | |||
392 | if (!sk) { | ||
383 | *err = -1; | 393 | *err = -1; |
384 | return; | 394 | return; |
385 | } | 395 | } |
386 | dst->value = sk_rmem_alloc_get(skb->sk); | 396 | dst->value = sk_rmem_alloc_get(sk); |
387 | } | 397 | } |
388 | 398 | ||
389 | META_COLLECTOR(int_sk_wmem_alloc) | 399 | META_COLLECTOR(int_sk_wmem_alloc) |
390 | { | 400 | { |
391 | if (skip_nonlocal(skb)) { | 401 | const struct sock *sk = skb_to_full_sk(skb); |
402 | |||
403 | if (!sk) { | ||
392 | *err = -1; | 404 | *err = -1; |
393 | return; | 405 | return; |
394 | } | 406 | } |
395 | dst->value = sk_wmem_alloc_get(skb->sk); | 407 | dst->value = sk_wmem_alloc_get(sk); |
396 | } | 408 | } |
397 | 409 | ||
398 | META_COLLECTOR(int_sk_omem_alloc) | 410 | META_COLLECTOR(int_sk_omem_alloc) |
399 | { | 411 | { |
400 | if (skip_nonlocal(skb)) { | 412 | const struct sock *sk = skb_to_full_sk(skb); |
413 | |||
414 | if (!sk) { | ||
401 | *err = -1; | 415 | *err = -1; |
402 | return; | 416 | return; |
403 | } | 417 | } |
404 | dst->value = atomic_read(&skb->sk->sk_omem_alloc); | 418 | dst->value = atomic_read(&sk->sk_omem_alloc); |
405 | } | 419 | } |
406 | 420 | ||
407 | META_COLLECTOR(int_sk_rcv_qlen) | 421 | META_COLLECTOR(int_sk_rcv_qlen) |
408 | { | 422 | { |
409 | if (skip_nonlocal(skb)) { | 423 | const struct sock *sk = skb_to_full_sk(skb); |
424 | |||
425 | if (!sk) { | ||
410 | *err = -1; | 426 | *err = -1; |
411 | return; | 427 | return; |
412 | } | 428 | } |
413 | dst->value = skb->sk->sk_receive_queue.qlen; | 429 | dst->value = sk->sk_receive_queue.qlen; |
414 | } | 430 | } |
415 | 431 | ||
416 | META_COLLECTOR(int_sk_snd_qlen) | 432 | META_COLLECTOR(int_sk_snd_qlen) |
417 | { | 433 | { |
418 | if (skip_nonlocal(skb)) { | 434 | const struct sock *sk = skb_to_full_sk(skb); |
435 | |||
436 | if (!sk) { | ||
419 | *err = -1; | 437 | *err = -1; |
420 | return; | 438 | return; |
421 | } | 439 | } |
422 | dst->value = skb->sk->sk_write_queue.qlen; | 440 | dst->value = sk->sk_write_queue.qlen; |
423 | } | 441 | } |
424 | 442 | ||
425 | META_COLLECTOR(int_sk_wmem_queued) | 443 | META_COLLECTOR(int_sk_wmem_queued) |
426 | { | 444 | { |
427 | if (skip_nonlocal(skb)) { | 445 | const struct sock *sk = skb_to_full_sk(skb); |
446 | |||
447 | if (!sk) { | ||
428 | *err = -1; | 448 | *err = -1; |
429 | return; | 449 | return; |
430 | } | 450 | } |
431 | dst->value = skb->sk->sk_wmem_queued; | 451 | dst->value = sk->sk_wmem_queued; |
432 | } | 452 | } |
433 | 453 | ||
434 | META_COLLECTOR(int_sk_fwd_alloc) | 454 | META_COLLECTOR(int_sk_fwd_alloc) |
435 | { | 455 | { |
436 | if (skip_nonlocal(skb)) { | 456 | const struct sock *sk = skb_to_full_sk(skb); |
457 | |||
458 | if (!sk) { | ||
437 | *err = -1; | 459 | *err = -1; |
438 | return; | 460 | return; |
439 | } | 461 | } |
440 | dst->value = skb->sk->sk_forward_alloc; | 462 | dst->value = sk->sk_forward_alloc; |
441 | } | 463 | } |
442 | 464 | ||
443 | META_COLLECTOR(int_sk_sndbuf) | 465 | META_COLLECTOR(int_sk_sndbuf) |
444 | { | 466 | { |
445 | if (skip_nonlocal(skb)) { | 467 | const struct sock *sk = skb_to_full_sk(skb); |
468 | |||
469 | if (!sk) { | ||
446 | *err = -1; | 470 | *err = -1; |
447 | return; | 471 | return; |
448 | } | 472 | } |
449 | dst->value = skb->sk->sk_sndbuf; | 473 | dst->value = sk->sk_sndbuf; |
450 | } | 474 | } |
451 | 475 | ||
452 | META_COLLECTOR(int_sk_alloc) | 476 | META_COLLECTOR(int_sk_alloc) |
453 | { | 477 | { |
454 | if (skip_nonlocal(skb)) { | 478 | const struct sock *sk = skb_to_full_sk(skb); |
479 | |||
480 | if (!sk) { | ||
455 | *err = -1; | 481 | *err = -1; |
456 | return; | 482 | return; |
457 | } | 483 | } |
458 | dst->value = (__force int) skb->sk->sk_allocation; | 484 | dst->value = (__force int) sk->sk_allocation; |
459 | } | 485 | } |
460 | 486 | ||
461 | META_COLLECTOR(int_sk_hash) | 487 | META_COLLECTOR(int_sk_hash) |
@@ -469,92 +495,112 @@ META_COLLECTOR(int_sk_hash) | |||
469 | 495 | ||
470 | META_COLLECTOR(int_sk_lingertime) | 496 | META_COLLECTOR(int_sk_lingertime) |
471 | { | 497 | { |
472 | if (skip_nonlocal(skb)) { | 498 | const struct sock *sk = skb_to_full_sk(skb); |
499 | |||
500 | if (!sk) { | ||
473 | *err = -1; | 501 | *err = -1; |
474 | return; | 502 | return; |
475 | } | 503 | } |
476 | dst->value = skb->sk->sk_lingertime / HZ; | 504 | dst->value = sk->sk_lingertime / HZ; |
477 | } | 505 | } |
478 | 506 | ||
479 | META_COLLECTOR(int_sk_err_qlen) | 507 | META_COLLECTOR(int_sk_err_qlen) |
480 | { | 508 | { |
481 | if (skip_nonlocal(skb)) { | 509 | const struct sock *sk = skb_to_full_sk(skb); |
510 | |||
511 | if (!sk) { | ||
482 | *err = -1; | 512 | *err = -1; |
483 | return; | 513 | return; |
484 | } | 514 | } |
485 | dst->value = skb->sk->sk_error_queue.qlen; | 515 | dst->value = sk->sk_error_queue.qlen; |
486 | } | 516 | } |
487 | 517 | ||
488 | META_COLLECTOR(int_sk_ack_bl) | 518 | META_COLLECTOR(int_sk_ack_bl) |
489 | { | 519 | { |
490 | if (skip_nonlocal(skb)) { | 520 | const struct sock *sk = skb_to_full_sk(skb); |
521 | |||
522 | if (!sk) { | ||
491 | *err = -1; | 523 | *err = -1; |
492 | return; | 524 | return; |
493 | } | 525 | } |
494 | dst->value = skb->sk->sk_ack_backlog; | 526 | dst->value = sk->sk_ack_backlog; |
495 | } | 527 | } |
496 | 528 | ||
497 | META_COLLECTOR(int_sk_max_ack_bl) | 529 | META_COLLECTOR(int_sk_max_ack_bl) |
498 | { | 530 | { |
499 | if (skip_nonlocal(skb)) { | 531 | const struct sock *sk = skb_to_full_sk(skb); |
532 | |||
533 | if (!sk) { | ||
500 | *err = -1; | 534 | *err = -1; |
501 | return; | 535 | return; |
502 | } | 536 | } |
503 | dst->value = skb->sk->sk_max_ack_backlog; | 537 | dst->value = sk->sk_max_ack_backlog; |
504 | } | 538 | } |
505 | 539 | ||
506 | META_COLLECTOR(int_sk_prio) | 540 | META_COLLECTOR(int_sk_prio) |
507 | { | 541 | { |
508 | if (skip_nonlocal(skb)) { | 542 | const struct sock *sk = skb_to_full_sk(skb); |
543 | |||
544 | if (!sk) { | ||
509 | *err = -1; | 545 | *err = -1; |
510 | return; | 546 | return; |
511 | } | 547 | } |
512 | dst->value = skb->sk->sk_priority; | 548 | dst->value = sk->sk_priority; |
513 | } | 549 | } |
514 | 550 | ||
515 | META_COLLECTOR(int_sk_rcvlowat) | 551 | META_COLLECTOR(int_sk_rcvlowat) |
516 | { | 552 | { |
517 | if (skip_nonlocal(skb)) { | 553 | const struct sock *sk = skb_to_full_sk(skb); |
554 | |||
555 | if (!sk) { | ||
518 | *err = -1; | 556 | *err = -1; |
519 | return; | 557 | return; |
520 | } | 558 | } |
521 | dst->value = skb->sk->sk_rcvlowat; | 559 | dst->value = sk->sk_rcvlowat; |
522 | } | 560 | } |
523 | 561 | ||
524 | META_COLLECTOR(int_sk_rcvtimeo) | 562 | META_COLLECTOR(int_sk_rcvtimeo) |
525 | { | 563 | { |
526 | if (skip_nonlocal(skb)) { | 564 | const struct sock *sk = skb_to_full_sk(skb); |
565 | |||
566 | if (!sk) { | ||
527 | *err = -1; | 567 | *err = -1; |
528 | return; | 568 | return; |
529 | } | 569 | } |
530 | dst->value = skb->sk->sk_rcvtimeo / HZ; | 570 | dst->value = sk->sk_rcvtimeo / HZ; |
531 | } | 571 | } |
532 | 572 | ||
533 | META_COLLECTOR(int_sk_sndtimeo) | 573 | META_COLLECTOR(int_sk_sndtimeo) |
534 | { | 574 | { |
535 | if (skip_nonlocal(skb)) { | 575 | const struct sock *sk = skb_to_full_sk(skb); |
576 | |||
577 | if (!sk) { | ||
536 | *err = -1; | 578 | *err = -1; |
537 | return; | 579 | return; |
538 | } | 580 | } |
539 | dst->value = skb->sk->sk_sndtimeo / HZ; | 581 | dst->value = sk->sk_sndtimeo / HZ; |
540 | } | 582 | } |
541 | 583 | ||
542 | META_COLLECTOR(int_sk_sendmsg_off) | 584 | META_COLLECTOR(int_sk_sendmsg_off) |
543 | { | 585 | { |
544 | if (skip_nonlocal(skb)) { | 586 | const struct sock *sk = skb_to_full_sk(skb); |
587 | |||
588 | if (!sk) { | ||
545 | *err = -1; | 589 | *err = -1; |
546 | return; | 590 | return; |
547 | } | 591 | } |
548 | dst->value = skb->sk->sk_frag.offset; | 592 | dst->value = sk->sk_frag.offset; |
549 | } | 593 | } |
550 | 594 | ||
551 | META_COLLECTOR(int_sk_write_pend) | 595 | META_COLLECTOR(int_sk_write_pend) |
552 | { | 596 | { |
553 | if (skip_nonlocal(skb)) { | 597 | const struct sock *sk = skb_to_full_sk(skb); |
598 | |||
599 | if (!sk) { | ||
554 | *err = -1; | 600 | *err = -1; |
555 | return; | 601 | return; |
556 | } | 602 | } |
557 | dst->value = skb->sk->sk_write_pending; | 603 | dst->value = sk->sk_write_pending; |
558 | } | 604 | } |
559 | 605 | ||
560 | /************************************************************************** | 606 | /************************************************************************** |
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index c9b2d5467477..23307da15f1d 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c | |||
@@ -4931,23 +4931,11 @@ static unsigned int selinux_ipv4_output(void *priv, | |||
4931 | return selinux_ip_output(skb, PF_INET); | 4931 | return selinux_ip_output(skb, PF_INET); |
4932 | } | 4932 | } |
4933 | 4933 | ||
4934 | /* SYNACK messages might be attached to request sockets. | ||
4935 | * To get back to sk_security, we need to look at the listener. | ||
4936 | */ | ||
4937 | static struct sock *selinux_skb_sk(const struct sk_buff *skb) | ||
4938 | { | ||
4939 | struct sock *sk = skb->sk; | ||
4940 | |||
4941 | if (sk && sk->sk_state == TCP_NEW_SYN_RECV) | ||
4942 | sk = inet_reqsk(sk)->rsk_listener; | ||
4943 | return sk; | ||
4944 | } | ||
4945 | |||
4946 | static unsigned int selinux_ip_postroute_compat(struct sk_buff *skb, | 4934 | static unsigned int selinux_ip_postroute_compat(struct sk_buff *skb, |
4947 | int ifindex, | 4935 | int ifindex, |
4948 | u16 family) | 4936 | u16 family) |
4949 | { | 4937 | { |
4950 | struct sock *sk = selinux_skb_sk(skb); | 4938 | struct sock *sk = skb_to_full_sk(skb); |
4951 | struct sk_security_struct *sksec; | 4939 | struct sk_security_struct *sksec; |
4952 | struct common_audit_data ad; | 4940 | struct common_audit_data ad; |
4953 | struct lsm_network_audit net = {0,}; | 4941 | struct lsm_network_audit net = {0,}; |
@@ -5002,7 +4990,7 @@ static unsigned int selinux_ip_postroute(struct sk_buff *skb, | |||
5002 | if (!secmark_active && !peerlbl_active) | 4990 | if (!secmark_active && !peerlbl_active) |
5003 | return NF_ACCEPT; | 4991 | return NF_ACCEPT; |
5004 | 4992 | ||
5005 | sk = selinux_skb_sk(skb); | 4993 | sk = skb_to_full_sk(skb); |
5006 | 4994 | ||
5007 | #ifdef CONFIG_XFRM | 4995 | #ifdef CONFIG_XFRM |
5008 | /* If skb->dst->xfrm is non-NULL then the packet is undergoing an IPsec | 4996 | /* If skb->dst->xfrm is non-NULL then the packet is undergoing an IPsec |
diff --git a/security/selinux/netlabel.c b/security/selinux/netlabel.c index 0364120d1ec8..1f989a539fd4 100644 --- a/security/selinux/netlabel.c +++ b/security/selinux/netlabel.c | |||
@@ -245,7 +245,7 @@ int selinux_netlbl_skbuff_setsid(struct sk_buff *skb, | |||
245 | 245 | ||
246 | /* if this is a locally generated packet check to see if it is already | 246 | /* if this is a locally generated packet check to see if it is already |
247 | * being labeled by it's parent socket, if it is just exit */ | 247 | * being labeled by it's parent socket, if it is just exit */ |
248 | sk = skb->sk; | 248 | sk = skb_to_full_sk(skb); |
249 | if (sk != NULL) { | 249 | if (sk != NULL) { |
250 | struct sk_security_struct *sksec = sk->sk_security; | 250 | struct sk_security_struct *sksec = sk->sk_security; |
251 | if (sksec->nlbl_state != NLBL_REQSKB) | 251 | if (sksec->nlbl_state != NLBL_REQSKB) |
diff --git a/security/smack/smack_netfilter.c b/security/smack/smack_netfilter.c index 6d1706c9777e..aa6bf1b22ec5 100644 --- a/security/smack/smack_netfilter.c +++ b/security/smack/smack_netfilter.c | |||
@@ -17,6 +17,7 @@ | |||
17 | #include <linux/netfilter_ipv4.h> | 17 | #include <linux/netfilter_ipv4.h> |
18 | #include <linux/netfilter_ipv6.h> | 18 | #include <linux/netfilter_ipv6.h> |
19 | #include <linux/netdevice.h> | 19 | #include <linux/netdevice.h> |
20 | #include <net/inet_sock.h> | ||
20 | #include "smack.h" | 21 | #include "smack.h" |
21 | 22 | ||
22 | #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) | 23 | #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) |
@@ -25,11 +26,12 @@ static unsigned int smack_ipv6_output(void *priv, | |||
25 | struct sk_buff *skb, | 26 | struct sk_buff *skb, |
26 | const struct nf_hook_state *state) | 27 | const struct nf_hook_state *state) |
27 | { | 28 | { |
29 | struct sock *sk = skb_to_full_sk(skb); | ||
28 | struct socket_smack *ssp; | 30 | struct socket_smack *ssp; |
29 | struct smack_known *skp; | 31 | struct smack_known *skp; |
30 | 32 | ||
31 | if (skb && skb->sk && skb->sk->sk_security) { | 33 | if (sk && sk->sk_security) { |
32 | ssp = skb->sk->sk_security; | 34 | ssp = sk->sk_security; |
33 | skp = ssp->smk_out; | 35 | skp = ssp->smk_out; |
34 | skb->secmark = skp->smk_secid; | 36 | skb->secmark = skp->smk_secid; |
35 | } | 37 | } |
@@ -42,11 +44,12 @@ static unsigned int smack_ipv4_output(void *priv, | |||
42 | struct sk_buff *skb, | 44 | struct sk_buff *skb, |
43 | const struct nf_hook_state *state) | 45 | const struct nf_hook_state *state) |
44 | { | 46 | { |
47 | struct sock *sk = skb_to_full_sk(skb); | ||
45 | struct socket_smack *ssp; | 48 | struct socket_smack *ssp; |
46 | struct smack_known *skp; | 49 | struct smack_known *skp; |
47 | 50 | ||
48 | if (skb && skb->sk && skb->sk->sk_security) { | 51 | if (sk && sk->sk_security) { |
49 | ssp = skb->sk->sk_security; | 52 | ssp = sk->sk_security; |
50 | skp = ssp->smk_out; | 53 | skp = ssp->smk_out; |
51 | skb->secmark = skp->smk_secid; | 54 | skb->secmark = skp->smk_secid; |
52 | } | 55 | } |