diff options
-rw-r--r-- | include/linux/security.h | 38 | ||||
-rw-r--r-- | include/net/route.h | 3 | ||||
-rw-r--r-- | net/dccp/ipv4.c | 1 | ||||
-rw-r--r-- | net/dccp/ipv6.c | 6 | ||||
-rw-r--r-- | net/ipv4/af_inet.c | 1 | ||||
-rw-r--r-- | net/ipv4/icmp.c | 2 | ||||
-rw-r--r-- | net/ipv4/inet_connection_sock.c | 1 | ||||
-rw-r--r-- | net/ipv4/ip_output.c | 2 | ||||
-rw-r--r-- | net/ipv4/netfilter/ipt_REJECT.c | 1 | ||||
-rw-r--r-- | net/ipv4/raw.c | 1 | ||||
-rw-r--r-- | net/ipv4/syncookies.c | 1 | ||||
-rw-r--r-- | net/ipv4/udp.c | 1 | ||||
-rw-r--r-- | net/ipv6/af_inet6.c | 1 | ||||
-rw-r--r-- | net/ipv6/datagram.c | 2 | ||||
-rw-r--r-- | net/ipv6/icmp.c | 2 | ||||
-rw-r--r-- | net/ipv6/inet6_connection_sock.c | 1 | ||||
-rw-r--r-- | net/ipv6/ndisc.c | 1 | ||||
-rw-r--r-- | net/ipv6/netfilter/ip6t_REJECT.c | 1 | ||||
-rw-r--r-- | net/ipv6/raw.c | 1 | ||||
-rw-r--r-- | net/ipv6/tcp_ipv6.c | 7 | ||||
-rw-r--r-- | net/ipv6/udp.c | 2 | ||||
-rw-r--r-- | net/xfrm/xfrm_policy.c | 3 | ||||
-rw-r--r-- | security/dummy.c | 7 | ||||
-rw-r--r-- | security/selinux/hooks.c | 8 | ||||
-rw-r--r-- | security/selinux/include/xfrm.h | 14 | ||||
-rw-r--r-- | security/selinux/xfrm.c | 11 |
26 files changed, 79 insertions, 40 deletions
diff --git a/include/linux/security.h b/include/linux/security.h index 2c4921d79d19..f3909d189fe0 100644 --- a/include/linux/security.h +++ b/include/linux/security.h | |||
@@ -32,6 +32,7 @@ | |||
32 | #include <linux/sched.h> | 32 | #include <linux/sched.h> |
33 | #include <linux/key.h> | 33 | #include <linux/key.h> |
34 | #include <linux/xfrm.h> | 34 | #include <linux/xfrm.h> |
35 | #include <net/flow.h> | ||
35 | 36 | ||
36 | struct ctl_table; | 37 | struct ctl_table; |
37 | 38 | ||
@@ -815,8 +816,8 @@ struct swap_info_struct; | |||
815 | * Deallocate security structure. | 816 | * Deallocate security structure. |
816 | * @sk_clone_security: | 817 | * @sk_clone_security: |
817 | * Clone/copy security structure. | 818 | * Clone/copy security structure. |
818 | * @sk_getsid: | 819 | * @sk_getsecid: |
819 | * Retrieve the LSM-specific sid for the sock to enable caching of network | 820 | * Retrieve the LSM-specific secid for the sock to enable caching of network |
820 | * authorizations. | 821 | * authorizations. |
821 | * | 822 | * |
822 | * Security hooks for XFRM operations. | 823 | * Security hooks for XFRM operations. |
@@ -882,8 +883,9 @@ struct swap_info_struct; | |||
882 | * Return 1 if there is a match. | 883 | * Return 1 if there is a match. |
883 | * @xfrm_decode_session: | 884 | * @xfrm_decode_session: |
884 | * @skb points to skb to decode. | 885 | * @skb points to skb to decode. |
885 | * @fl points to the flow key to set. | 886 | * @secid points to the flow key secid to set. |
886 | * Return 0 if successful decoding. | 887 | * @ckall says if all xfrms used should be checked for same secid. |
888 | * Return 0 if ckall is zero or all xfrms used have the same secid. | ||
887 | * | 889 | * |
888 | * Security hooks affecting all Key Management operations | 890 | * Security hooks affecting all Key Management operations |
889 | * | 891 | * |
@@ -1353,7 +1355,7 @@ struct security_operations { | |||
1353 | int (*sk_alloc_security) (struct sock *sk, int family, gfp_t priority); | 1355 | int (*sk_alloc_security) (struct sock *sk, int family, gfp_t priority); |
1354 | void (*sk_free_security) (struct sock *sk); | 1356 | void (*sk_free_security) (struct sock *sk); |
1355 | void (*sk_clone_security) (const struct sock *sk, struct sock *newsk); | 1357 | void (*sk_clone_security) (const struct sock *sk, struct sock *newsk); |
1356 | unsigned int (*sk_getsid) (struct sock *sk, struct flowi *fl, u8 dir); | 1358 | void (*sk_getsecid) (struct sock *sk, u32 *secid); |
1357 | #endif /* CONFIG_SECURITY_NETWORK */ | 1359 | #endif /* CONFIG_SECURITY_NETWORK */ |
1358 | 1360 | ||
1359 | #ifdef CONFIG_SECURITY_NETWORK_XFRM | 1361 | #ifdef CONFIG_SECURITY_NETWORK_XFRM |
@@ -1370,7 +1372,7 @@ struct security_operations { | |||
1370 | int (*xfrm_state_pol_flow_match)(struct xfrm_state *x, | 1372 | int (*xfrm_state_pol_flow_match)(struct xfrm_state *x, |
1371 | struct xfrm_policy *xp, struct flowi *fl); | 1373 | struct xfrm_policy *xp, struct flowi *fl); |
1372 | int (*xfrm_flow_state_match)(struct flowi *fl, struct xfrm_state *xfrm); | 1374 | int (*xfrm_flow_state_match)(struct flowi *fl, struct xfrm_state *xfrm); |
1373 | int (*xfrm_decode_session)(struct sk_buff *skb, struct flowi *fl); | 1375 | int (*xfrm_decode_session)(struct sk_buff *skb, u32 *secid, int ckall); |
1374 | #endif /* CONFIG_SECURITY_NETWORK_XFRM */ | 1376 | #endif /* CONFIG_SECURITY_NETWORK_XFRM */ |
1375 | 1377 | ||
1376 | /* key management security hooks */ | 1378 | /* key management security hooks */ |
@@ -2917,9 +2919,9 @@ static inline void security_sk_clone(const struct sock *sk, struct sock *newsk) | |||
2917 | return security_ops->sk_clone_security(sk, newsk); | 2919 | return security_ops->sk_clone_security(sk, newsk); |
2918 | } | 2920 | } |
2919 | 2921 | ||
2920 | static inline unsigned int security_sk_sid(struct sock *sk, struct flowi *fl, u8 dir) | 2922 | static inline void security_sk_classify_flow(struct sock *sk, struct flowi *fl) |
2921 | { | 2923 | { |
2922 | return security_ops->sk_getsid(sk, fl, dir); | 2924 | security_ops->sk_getsecid(sk, &fl->secid); |
2923 | } | 2925 | } |
2924 | #else /* CONFIG_SECURITY_NETWORK */ | 2926 | #else /* CONFIG_SECURITY_NETWORK */ |
2925 | static inline int security_unix_stream_connect(struct socket * sock, | 2927 | static inline int security_unix_stream_connect(struct socket * sock, |
@@ -3047,9 +3049,8 @@ static inline void security_sk_clone(const struct sock *sk, struct sock *newsk) | |||
3047 | { | 3049 | { |
3048 | } | 3050 | } |
3049 | 3051 | ||
3050 | static inline unsigned int security_sk_sid(struct sock *sk, struct flowi *fl, u8 dir) | 3052 | static inline void security_sk_classify_flow(struct sock *sk, struct flowi *fl) |
3051 | { | 3053 | { |
3052 | return 0; | ||
3053 | } | 3054 | } |
3054 | #endif /* CONFIG_SECURITY_NETWORK */ | 3055 | #endif /* CONFIG_SECURITY_NETWORK */ |
3055 | 3056 | ||
@@ -3114,9 +3115,16 @@ static inline int security_xfrm_flow_state_match(struct flowi *fl, struct xfrm_s | |||
3114 | return security_ops->xfrm_flow_state_match(fl, xfrm); | 3115 | return security_ops->xfrm_flow_state_match(fl, xfrm); |
3115 | } | 3116 | } |
3116 | 3117 | ||
3117 | static inline int security_xfrm_decode_session(struct sk_buff *skb, struct flowi *fl) | 3118 | static inline int security_xfrm_decode_session(struct sk_buff *skb, u32 *secid) |
3119 | { | ||
3120 | return security_ops->xfrm_decode_session(skb, secid, 1); | ||
3121 | } | ||
3122 | |||
3123 | static inline void security_skb_classify_flow(struct sk_buff *skb, struct flowi *fl) | ||
3118 | { | 3124 | { |
3119 | return security_ops->xfrm_decode_session(skb, fl); | 3125 | int rc = security_ops->xfrm_decode_session(skb, &fl->secid, 0); |
3126 | |||
3127 | BUG_ON(rc); | ||
3120 | } | 3128 | } |
3121 | #else /* CONFIG_SECURITY_NETWORK_XFRM */ | 3129 | #else /* CONFIG_SECURITY_NETWORK_XFRM */ |
3122 | static inline int security_xfrm_policy_alloc(struct xfrm_policy *xp, struct xfrm_user_sec_ctx *sec_ctx) | 3130 | static inline int security_xfrm_policy_alloc(struct xfrm_policy *xp, struct xfrm_user_sec_ctx *sec_ctx) |
@@ -3176,11 +3184,15 @@ static inline int security_xfrm_flow_state_match(struct flowi *fl, | |||
3176 | return 1; | 3184 | return 1; |
3177 | } | 3185 | } |
3178 | 3186 | ||
3179 | static inline int security_xfrm_decode_session(struct sk_buff *skb, struct flowi *fl) | 3187 | static inline int security_xfrm_decode_session(struct sk_buff *skb, u32 *secid) |
3180 | { | 3188 | { |
3181 | return 0; | 3189 | return 0; |
3182 | } | 3190 | } |
3183 | 3191 | ||
3192 | static inline void security_skb_classify_flow(struct sk_buff *skb, struct flowi *fl) | ||
3193 | { | ||
3194 | } | ||
3195 | |||
3184 | #endif /* CONFIG_SECURITY_NETWORK_XFRM */ | 3196 | #endif /* CONFIG_SECURITY_NETWORK_XFRM */ |
3185 | 3197 | ||
3186 | #ifdef CONFIG_KEYS | 3198 | #ifdef CONFIG_KEYS |
diff --git a/include/net/route.h b/include/net/route.h index c4a068692dcc..7f93ac0e0899 100644 --- a/include/net/route.h +++ b/include/net/route.h | |||
@@ -32,6 +32,7 @@ | |||
32 | #include <linux/route.h> | 32 | #include <linux/route.h> |
33 | #include <linux/ip.h> | 33 | #include <linux/ip.h> |
34 | #include <linux/cache.h> | 34 | #include <linux/cache.h> |
35 | #include <linux/security.h> | ||
35 | 36 | ||
36 | #ifndef __KERNEL__ | 37 | #ifndef __KERNEL__ |
37 | #warning This file is not supposed to be used outside of kernel. | 38 | #warning This file is not supposed to be used outside of kernel. |
@@ -166,6 +167,7 @@ static inline int ip_route_connect(struct rtable **rp, u32 dst, | |||
166 | ip_rt_put(*rp); | 167 | ip_rt_put(*rp); |
167 | *rp = NULL; | 168 | *rp = NULL; |
168 | } | 169 | } |
170 | security_sk_classify_flow(sk, &fl); | ||
169 | return ip_route_output_flow(rp, &fl, sk, 0); | 171 | return ip_route_output_flow(rp, &fl, sk, 0); |
170 | } | 172 | } |
171 | 173 | ||
@@ -182,6 +184,7 @@ static inline int ip_route_newports(struct rtable **rp, u8 protocol, | |||
182 | fl.proto = protocol; | 184 | fl.proto = protocol; |
183 | ip_rt_put(*rp); | 185 | ip_rt_put(*rp); |
184 | *rp = NULL; | 186 | *rp = NULL; |
187 | security_sk_classify_flow(sk, &fl); | ||
185 | return ip_route_output_flow(rp, &fl, sk, 0); | 188 | return ip_route_output_flow(rp, &fl, sk, 0); |
186 | } | 189 | } |
187 | return 0; | 190 | return 0; |
diff --git a/net/dccp/ipv4.c b/net/dccp/ipv4.c index 7f56f7e8f571..386498053b1c 100644 --- a/net/dccp/ipv4.c +++ b/net/dccp/ipv4.c | |||
@@ -678,6 +678,7 @@ static struct dst_entry* dccp_v4_route_skb(struct sock *sk, | |||
678 | } | 678 | } |
679 | }; | 679 | }; |
680 | 680 | ||
681 | security_skb_classify_flow(skb, &fl); | ||
681 | if (ip_route_output_flow(&rt, &fl, sk, 0)) { | 682 | if (ip_route_output_flow(&rt, &fl, sk, 0)) { |
682 | IP_INC_STATS_BH(IPSTATS_MIB_OUTNOROUTES); | 683 | IP_INC_STATS_BH(IPSTATS_MIB_OUTNOROUTES); |
683 | return NULL; | 684 | return NULL; |
diff --git a/net/dccp/ipv6.c b/net/dccp/ipv6.c index 610c722ac27f..53d255c01431 100644 --- a/net/dccp/ipv6.c +++ b/net/dccp/ipv6.c | |||
@@ -201,6 +201,7 @@ static int dccp_v6_connect(struct sock *sk, struct sockaddr *uaddr, | |||
201 | fl.oif = sk->sk_bound_dev_if; | 201 | fl.oif = sk->sk_bound_dev_if; |
202 | fl.fl_ip_dport = usin->sin6_port; | 202 | fl.fl_ip_dport = usin->sin6_port; |
203 | fl.fl_ip_sport = inet->sport; | 203 | fl.fl_ip_sport = inet->sport; |
204 | security_sk_classify_flow(sk, &fl); | ||
204 | 205 | ||
205 | if (np->opt != NULL && np->opt->srcrt != NULL) { | 206 | if (np->opt != NULL && np->opt->srcrt != NULL) { |
206 | const struct rt0_hdr *rt0 = (struct rt0_hdr *)np->opt->srcrt; | 207 | const struct rt0_hdr *rt0 = (struct rt0_hdr *)np->opt->srcrt; |
@@ -322,6 +323,7 @@ static void dccp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, | |||
322 | fl.oif = sk->sk_bound_dev_if; | 323 | fl.oif = sk->sk_bound_dev_if; |
323 | fl.fl_ip_dport = inet->dport; | 324 | fl.fl_ip_dport = inet->dport; |
324 | fl.fl_ip_sport = inet->sport; | 325 | fl.fl_ip_sport = inet->sport; |
326 | security_sk_classify_flow(sk, &fl); | ||
325 | 327 | ||
326 | err = ip6_dst_lookup(sk, &dst, &fl); | 328 | err = ip6_dst_lookup(sk, &dst, &fl); |
327 | if (err) { | 329 | if (err) { |
@@ -422,6 +424,7 @@ static int dccp_v6_send_response(struct sock *sk, struct request_sock *req, | |||
422 | fl.oif = ireq6->iif; | 424 | fl.oif = ireq6->iif; |
423 | fl.fl_ip_dport = inet_rsk(req)->rmt_port; | 425 | fl.fl_ip_dport = inet_rsk(req)->rmt_port; |
424 | fl.fl_ip_sport = inet_sk(sk)->sport; | 426 | fl.fl_ip_sport = inet_sk(sk)->sport; |
427 | security_sk_classify_flow(sk, &fl); | ||
425 | 428 | ||
426 | if (dst == NULL) { | 429 | if (dst == NULL) { |
427 | opt = np->opt; | 430 | opt = np->opt; |
@@ -566,6 +569,7 @@ static void dccp_v6_ctl_send_reset(struct sk_buff *rxskb) | |||
566 | fl.oif = inet6_iif(rxskb); | 569 | fl.oif = inet6_iif(rxskb); |
567 | fl.fl_ip_dport = dh->dccph_dport; | 570 | fl.fl_ip_dport = dh->dccph_dport; |
568 | fl.fl_ip_sport = dh->dccph_sport; | 571 | fl.fl_ip_sport = dh->dccph_sport; |
572 | security_skb_classify_flow(rxskb, &fl); | ||
569 | 573 | ||
570 | /* sk = NULL, but it is safe for now. RST socket required. */ | 574 | /* sk = NULL, but it is safe for now. RST socket required. */ |
571 | if (!ip6_dst_lookup(NULL, &skb->dst, &fl)) { | 575 | if (!ip6_dst_lookup(NULL, &skb->dst, &fl)) { |
@@ -622,6 +626,7 @@ static void dccp_v6_reqsk_send_ack(struct sk_buff *rxskb, | |||
622 | fl.oif = inet6_iif(rxskb); | 626 | fl.oif = inet6_iif(rxskb); |
623 | fl.fl_ip_dport = dh->dccph_dport; | 627 | fl.fl_ip_dport = dh->dccph_dport; |
624 | fl.fl_ip_sport = dh->dccph_sport; | 628 | fl.fl_ip_sport = dh->dccph_sport; |
629 | security_skb_classify_flow(rxskb, &fl); | ||
625 | 630 | ||
626 | if (!ip6_dst_lookup(NULL, &skb->dst, &fl)) { | 631 | if (!ip6_dst_lookup(NULL, &skb->dst, &fl)) { |
627 | if (xfrm_lookup(&skb->dst, &fl, NULL, 0) >= 0) { | 632 | if (xfrm_lookup(&skb->dst, &fl, NULL, 0) >= 0) { |
@@ -842,6 +847,7 @@ static struct sock *dccp_v6_request_recv_sock(struct sock *sk, | |||
842 | fl.oif = sk->sk_bound_dev_if; | 847 | fl.oif = sk->sk_bound_dev_if; |
843 | fl.fl_ip_dport = inet_rsk(req)->rmt_port; | 848 | fl.fl_ip_dport = inet_rsk(req)->rmt_port; |
844 | fl.fl_ip_sport = inet_sk(sk)->sport; | 849 | fl.fl_ip_sport = inet_sk(sk)->sport; |
850 | security_sk_classify_flow(sk, &fl); | ||
845 | 851 | ||
846 | if (ip6_dst_lookup(sk, &dst, &fl)) | 852 | if (ip6_dst_lookup(sk, &dst, &fl)) |
847 | goto out; | 853 | goto out; |
diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c index c84a32070f8d..fc40da3b6d39 100644 --- a/net/ipv4/af_inet.c +++ b/net/ipv4/af_inet.c | |||
@@ -1074,6 +1074,7 @@ int inet_sk_rebuild_header(struct sock *sk) | |||
1074 | }, | 1074 | }, |
1075 | }; | 1075 | }; |
1076 | 1076 | ||
1077 | security_sk_classify_flow(sk, &fl); | ||
1077 | err = ip_route_output_flow(&rt, &fl, sk, 0); | 1078 | err = ip_route_output_flow(&rt, &fl, sk, 0); |
1078 | } | 1079 | } |
1079 | if (!err) | 1080 | if (!err) |
diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c index 4c86ac3d882d..6ad797c14163 100644 --- a/net/ipv4/icmp.c +++ b/net/ipv4/icmp.c | |||
@@ -406,6 +406,7 @@ static void icmp_reply(struct icmp_bxm *icmp_param, struct sk_buff *skb) | |||
406 | .saddr = rt->rt_spec_dst, | 406 | .saddr = rt->rt_spec_dst, |
407 | .tos = RT_TOS(skb->nh.iph->tos) } }, | 407 | .tos = RT_TOS(skb->nh.iph->tos) } }, |
408 | .proto = IPPROTO_ICMP }; | 408 | .proto = IPPROTO_ICMP }; |
409 | security_skb_classify_flow(skb, &fl); | ||
409 | if (ip_route_output_key(&rt, &fl)) | 410 | if (ip_route_output_key(&rt, &fl)) |
410 | goto out_unlock; | 411 | goto out_unlock; |
411 | } | 412 | } |
@@ -560,6 +561,7 @@ void icmp_send(struct sk_buff *skb_in, int type, int code, u32 info) | |||
560 | } | 561 | } |
561 | } | 562 | } |
562 | }; | 563 | }; |
564 | security_skb_classify_flow(skb_in, &fl); | ||
563 | if (ip_route_output_key(&rt, &fl)) | 565 | if (ip_route_output_key(&rt, &fl)) |
564 | goto out_unlock; | 566 | goto out_unlock; |
565 | } | 567 | } |
diff --git a/net/ipv4/inet_connection_sock.c b/net/ipv4/inet_connection_sock.c index e50a1bfd7ccc..772b4eac78bc 100644 --- a/net/ipv4/inet_connection_sock.c +++ b/net/ipv4/inet_connection_sock.c | |||
@@ -327,6 +327,7 @@ struct dst_entry* inet_csk_route_req(struct sock *sk, | |||
327 | { .sport = inet_sk(sk)->sport, | 327 | { .sport = inet_sk(sk)->sport, |
328 | .dport = ireq->rmt_port } } }; | 328 | .dport = ireq->rmt_port } } }; |
329 | 329 | ||
330 | security_sk_classify_flow(sk, &fl); | ||
330 | if (ip_route_output_flow(&rt, &fl, sk, 0)) { | 331 | if (ip_route_output_flow(&rt, &fl, sk, 0)) { |
331 | IP_INC_STATS_BH(IPSTATS_MIB_OUTNOROUTES); | 332 | IP_INC_STATS_BH(IPSTATS_MIB_OUTNOROUTES); |
332 | return NULL; | 333 | return NULL; |
diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c index a2ede167e045..308bdeac3455 100644 --- a/net/ipv4/ip_output.c +++ b/net/ipv4/ip_output.c | |||
@@ -328,6 +328,7 @@ int ip_queue_xmit(struct sk_buff *skb, int ipfragok) | |||
328 | * keep trying until route appears or the connection times | 328 | * keep trying until route appears or the connection times |
329 | * itself out. | 329 | * itself out. |
330 | */ | 330 | */ |
331 | security_sk_classify_flow(sk, &fl); | ||
331 | if (ip_route_output_flow(&rt, &fl, sk, 0)) | 332 | if (ip_route_output_flow(&rt, &fl, sk, 0)) |
332 | goto no_route; | 333 | goto no_route; |
333 | } | 334 | } |
@@ -1366,6 +1367,7 @@ void ip_send_reply(struct sock *sk, struct sk_buff *skb, struct ip_reply_arg *ar | |||
1366 | { .sport = skb->h.th->dest, | 1367 | { .sport = skb->h.th->dest, |
1367 | .dport = skb->h.th->source } }, | 1368 | .dport = skb->h.th->source } }, |
1368 | .proto = sk->sk_protocol }; | 1369 | .proto = sk->sk_protocol }; |
1370 | security_skb_classify_flow(skb, &fl); | ||
1369 | if (ip_route_output_key(&rt, &fl)) | 1371 | if (ip_route_output_key(&rt, &fl)) |
1370 | return; | 1372 | return; |
1371 | } | 1373 | } |
diff --git a/net/ipv4/netfilter/ipt_REJECT.c b/net/ipv4/netfilter/ipt_REJECT.c index 269bc2067cb8..7f905bf2bde5 100644 --- a/net/ipv4/netfilter/ipt_REJECT.c +++ b/net/ipv4/netfilter/ipt_REJECT.c | |||
@@ -90,6 +90,7 @@ static inline struct rtable *route_reverse(struct sk_buff *skb, | |||
90 | fl.proto = IPPROTO_TCP; | 90 | fl.proto = IPPROTO_TCP; |
91 | fl.fl_ip_sport = tcph->dest; | 91 | fl.fl_ip_sport = tcph->dest; |
92 | fl.fl_ip_dport = tcph->source; | 92 | fl.fl_ip_dport = tcph->source; |
93 | security_skb_classify_flow(skb, &fl); | ||
93 | 94 | ||
94 | xfrm_lookup((struct dst_entry **)&rt, &fl, NULL, 0); | 95 | xfrm_lookup((struct dst_entry **)&rt, &fl, NULL, 0); |
95 | 96 | ||
diff --git a/net/ipv4/raw.c b/net/ipv4/raw.c index 62b2762a2420..fe44cb50a1c5 100644 --- a/net/ipv4/raw.c +++ b/net/ipv4/raw.c | |||
@@ -484,6 +484,7 @@ static int raw_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, | |||
484 | if (!inet->hdrincl) | 484 | if (!inet->hdrincl) |
485 | raw_probe_proto_opt(&fl, msg); | 485 | raw_probe_proto_opt(&fl, msg); |
486 | 486 | ||
487 | security_sk_classify_flow(sk, &fl); | ||
487 | err = ip_route_output_flow(&rt, &fl, sk, !(msg->msg_flags&MSG_DONTWAIT)); | 488 | err = ip_route_output_flow(&rt, &fl, sk, !(msg->msg_flags&MSG_DONTWAIT)); |
488 | } | 489 | } |
489 | if (err) | 490 | if (err) |
diff --git a/net/ipv4/syncookies.c b/net/ipv4/syncookies.c index e20be3331f67..307dc3c0d635 100644 --- a/net/ipv4/syncookies.c +++ b/net/ipv4/syncookies.c | |||
@@ -259,6 +259,7 @@ struct sock *cookie_v4_check(struct sock *sk, struct sk_buff *skb, | |||
259 | .uli_u = { .ports = | 259 | .uli_u = { .ports = |
260 | { .sport = skb->h.th->dest, | 260 | { .sport = skb->h.th->dest, |
261 | .dport = skb->h.th->source } } }; | 261 | .dport = skb->h.th->source } } }; |
262 | security_sk_classify_flow(sk, &fl); | ||
262 | if (ip_route_output_key(&rt, &fl)) { | 263 | if (ip_route_output_key(&rt, &fl)) { |
263 | reqsk_free(req); | 264 | reqsk_free(req); |
264 | goto out; | 265 | goto out; |
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c index f136cec96d95..a4d005eccc7f 100644 --- a/net/ipv4/udp.c +++ b/net/ipv4/udp.c | |||
@@ -603,6 +603,7 @@ int udp_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, | |||
603 | .uli_u = { .ports = | 603 | .uli_u = { .ports = |
604 | { .sport = inet->sport, | 604 | { .sport = inet->sport, |
605 | .dport = dport } } }; | 605 | .dport = dport } } }; |
606 | security_sk_classify_flow(sk, &fl); | ||
606 | err = ip_route_output_flow(&rt, &fl, sk, !(msg->msg_flags&MSG_DONTWAIT)); | 607 | err = ip_route_output_flow(&rt, &fl, sk, !(msg->msg_flags&MSG_DONTWAIT)); |
607 | if (err) | 608 | if (err) |
608 | goto out; | 609 | goto out; |
diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c index ac85e9c532c2..82a1b1a328db 100644 --- a/net/ipv6/af_inet6.c +++ b/net/ipv6/af_inet6.c | |||
@@ -637,6 +637,7 @@ int inet6_sk_rebuild_header(struct sock *sk) | |||
637 | fl.oif = sk->sk_bound_dev_if; | 637 | fl.oif = sk->sk_bound_dev_if; |
638 | fl.fl_ip_dport = inet->dport; | 638 | fl.fl_ip_dport = inet->dport; |
639 | fl.fl_ip_sport = inet->sport; | 639 | fl.fl_ip_sport = inet->sport; |
640 | security_sk_classify_flow(sk, &fl); | ||
640 | 641 | ||
641 | if (np->opt && np->opt->srcrt) { | 642 | if (np->opt && np->opt->srcrt) { |
642 | struct rt0_hdr *rt0 = (struct rt0_hdr *) np->opt->srcrt; | 643 | struct rt0_hdr *rt0 = (struct rt0_hdr *) np->opt->srcrt; |
diff --git a/net/ipv6/datagram.c b/net/ipv6/datagram.c index 3b55b4c8e2d1..c73508e090a6 100644 --- a/net/ipv6/datagram.c +++ b/net/ipv6/datagram.c | |||
@@ -156,6 +156,8 @@ ipv4_connected: | |||
156 | if (!fl.oif && (addr_type&IPV6_ADDR_MULTICAST)) | 156 | if (!fl.oif && (addr_type&IPV6_ADDR_MULTICAST)) |
157 | fl.oif = np->mcast_oif; | 157 | fl.oif = np->mcast_oif; |
158 | 158 | ||
159 | security_sk_classify_flow(sk, &fl); | ||
160 | |||
159 | if (flowlabel) { | 161 | if (flowlabel) { |
160 | if (flowlabel->opt && flowlabel->opt->srcrt) { | 162 | if (flowlabel->opt && flowlabel->opt->srcrt) { |
161 | struct rt0_hdr *rt0 = (struct rt0_hdr *) flowlabel->opt->srcrt; | 163 | struct rt0_hdr *rt0 = (struct rt0_hdr *) flowlabel->opt->srcrt; |
diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c index 356a8a7ef22a..dbfce089e916 100644 --- a/net/ipv6/icmp.c +++ b/net/ipv6/icmp.c | |||
@@ -358,6 +358,7 @@ void icmpv6_send(struct sk_buff *skb, int type, int code, __u32 info, | |||
358 | fl.oif = iif; | 358 | fl.oif = iif; |
359 | fl.fl_icmp_type = type; | 359 | fl.fl_icmp_type = type; |
360 | fl.fl_icmp_code = code; | 360 | fl.fl_icmp_code = code; |
361 | security_skb_classify_flow(skb, &fl); | ||
361 | 362 | ||
362 | if (icmpv6_xmit_lock()) | 363 | if (icmpv6_xmit_lock()) |
363 | return; | 364 | return; |
@@ -472,6 +473,7 @@ static void icmpv6_echo_reply(struct sk_buff *skb) | |||
472 | ipv6_addr_copy(&fl.fl6_src, saddr); | 473 | ipv6_addr_copy(&fl.fl6_src, saddr); |
473 | fl.oif = skb->dev->ifindex; | 474 | fl.oif = skb->dev->ifindex; |
474 | fl.fl_icmp_type = ICMPV6_ECHO_REPLY; | 475 | fl.fl_icmp_type = ICMPV6_ECHO_REPLY; |
476 | security_skb_classify_flow(skb, &fl); | ||
475 | 477 | ||
476 | if (icmpv6_xmit_lock()) | 478 | if (icmpv6_xmit_lock()) |
477 | return; | 479 | return; |
diff --git a/net/ipv6/inet6_connection_sock.c b/net/ipv6/inet6_connection_sock.c index bf491077b822..7a51a258615d 100644 --- a/net/ipv6/inet6_connection_sock.c +++ b/net/ipv6/inet6_connection_sock.c | |||
@@ -157,6 +157,7 @@ int inet6_csk_xmit(struct sk_buff *skb, int ipfragok) | |||
157 | fl.oif = sk->sk_bound_dev_if; | 157 | fl.oif = sk->sk_bound_dev_if; |
158 | fl.fl_ip_sport = inet->sport; | 158 | fl.fl_ip_sport = inet->sport; |
159 | fl.fl_ip_dport = inet->dport; | 159 | fl.fl_ip_dport = inet->dport; |
160 | security_sk_classify_flow(sk, &fl); | ||
160 | 161 | ||
161 | if (np->opt && np->opt->srcrt) { | 162 | if (np->opt && np->opt->srcrt) { |
162 | struct rt0_hdr *rt0 = (struct rt0_hdr *)np->opt->srcrt; | 163 | struct rt0_hdr *rt0 = (struct rt0_hdr *)np->opt->srcrt; |
diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c index b50055b9278d..67cfc3813c32 100644 --- a/net/ipv6/ndisc.c +++ b/net/ipv6/ndisc.c | |||
@@ -419,6 +419,7 @@ static inline void ndisc_flow_init(struct flowi *fl, u8 type, | |||
419 | fl->proto = IPPROTO_ICMPV6; | 419 | fl->proto = IPPROTO_ICMPV6; |
420 | fl->fl_icmp_type = type; | 420 | fl->fl_icmp_type = type; |
421 | fl->fl_icmp_code = 0; | 421 | fl->fl_icmp_code = 0; |
422 | security_sk_classify_flow(ndisc_socket->sk, fl); | ||
422 | } | 423 | } |
423 | 424 | ||
424 | static void ndisc_send_na(struct net_device *dev, struct neighbour *neigh, | 425 | static void ndisc_send_na(struct net_device *dev, struct neighbour *neigh, |
diff --git a/net/ipv6/netfilter/ip6t_REJECT.c b/net/ipv6/netfilter/ip6t_REJECT.c index 8629ba195d2d..c4eba1aeb323 100644 --- a/net/ipv6/netfilter/ip6t_REJECT.c +++ b/net/ipv6/netfilter/ip6t_REJECT.c | |||
@@ -96,6 +96,7 @@ static void send_reset(struct sk_buff *oldskb) | |||
96 | ipv6_addr_copy(&fl.fl6_dst, &oip6h->saddr); | 96 | ipv6_addr_copy(&fl.fl6_dst, &oip6h->saddr); |
97 | fl.fl_ip_sport = otcph.dest; | 97 | fl.fl_ip_sport = otcph.dest; |
98 | fl.fl_ip_dport = otcph.source; | 98 | fl.fl_ip_dport = otcph.source; |
99 | security_skb_classify_flow(oldskb, &fl); | ||
99 | dst = ip6_route_output(NULL, &fl); | 100 | dst = ip6_route_output(NULL, &fl); |
100 | if (dst == NULL) | 101 | if (dst == NULL) |
101 | return; | 102 | return; |
diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c index 15b862d8acab..d5040e172292 100644 --- a/net/ipv6/raw.c +++ b/net/ipv6/raw.c | |||
@@ -759,6 +759,7 @@ static int rawv6_sendmsg(struct kiocb *iocb, struct sock *sk, | |||
759 | 759 | ||
760 | if (!fl.oif && ipv6_addr_is_multicast(&fl.fl6_dst)) | 760 | if (!fl.oif && ipv6_addr_is_multicast(&fl.fl6_dst)) |
761 | fl.oif = np->mcast_oif; | 761 | fl.oif = np->mcast_oif; |
762 | security_sk_classify_flow(sk, &fl); | ||
762 | 763 | ||
763 | err = ip6_dst_lookup(sk, &dst, &fl); | 764 | err = ip6_dst_lookup(sk, &dst, &fl); |
764 | if (err) | 765 | if (err) |
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c index 802a1a6b1037..46922e57e311 100644 --- a/net/ipv6/tcp_ipv6.c +++ b/net/ipv6/tcp_ipv6.c | |||
@@ -251,6 +251,8 @@ static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr, | |||
251 | final_p = &final; | 251 | final_p = &final; |
252 | } | 252 | } |
253 | 253 | ||
254 | security_sk_classify_flow(sk, &fl); | ||
255 | |||
254 | err = ip6_dst_lookup(sk, &dst, &fl); | 256 | err = ip6_dst_lookup(sk, &dst, &fl); |
255 | if (err) | 257 | if (err) |
256 | goto failure; | 258 | goto failure; |
@@ -374,6 +376,7 @@ static void tcp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, | |||
374 | fl.oif = sk->sk_bound_dev_if; | 376 | fl.oif = sk->sk_bound_dev_if; |
375 | fl.fl_ip_dport = inet->dport; | 377 | fl.fl_ip_dport = inet->dport; |
376 | fl.fl_ip_sport = inet->sport; | 378 | fl.fl_ip_sport = inet->sport; |
379 | security_skb_classify_flow(skb, &fl); | ||
377 | 380 | ||
378 | if ((err = ip6_dst_lookup(sk, &dst, &fl))) { | 381 | if ((err = ip6_dst_lookup(sk, &dst, &fl))) { |
379 | sk->sk_err_soft = -err; | 382 | sk->sk_err_soft = -err; |
@@ -467,6 +470,7 @@ static int tcp_v6_send_synack(struct sock *sk, struct request_sock *req, | |||
467 | fl.oif = treq->iif; | 470 | fl.oif = treq->iif; |
468 | fl.fl_ip_dport = inet_rsk(req)->rmt_port; | 471 | fl.fl_ip_dport = inet_rsk(req)->rmt_port; |
469 | fl.fl_ip_sport = inet_sk(sk)->sport; | 472 | fl.fl_ip_sport = inet_sk(sk)->sport; |
473 | security_sk_classify_flow(sk, &fl); | ||
470 | 474 | ||
471 | if (dst == NULL) { | 475 | if (dst == NULL) { |
472 | opt = np->opt; | 476 | opt = np->opt; |
@@ -625,6 +629,7 @@ static void tcp_v6_send_reset(struct sk_buff *skb) | |||
625 | fl.oif = inet6_iif(skb); | 629 | fl.oif = inet6_iif(skb); |
626 | fl.fl_ip_dport = t1->dest; | 630 | fl.fl_ip_dport = t1->dest; |
627 | fl.fl_ip_sport = t1->source; | 631 | fl.fl_ip_sport = t1->source; |
632 | security_skb_classify_flow(skb, &fl); | ||
628 | 633 | ||
629 | /* sk = NULL, but it is safe for now. RST socket required. */ | 634 | /* sk = NULL, but it is safe for now. RST socket required. */ |
630 | if (!ip6_dst_lookup(NULL, &buff->dst, &fl)) { | 635 | if (!ip6_dst_lookup(NULL, &buff->dst, &fl)) { |
@@ -691,6 +696,7 @@ static void tcp_v6_send_ack(struct sk_buff *skb, u32 seq, u32 ack, u32 win, u32 | |||
691 | fl.oif = inet6_iif(skb); | 696 | fl.oif = inet6_iif(skb); |
692 | fl.fl_ip_dport = t1->dest; | 697 | fl.fl_ip_dport = t1->dest; |
693 | fl.fl_ip_sport = t1->source; | 698 | fl.fl_ip_sport = t1->source; |
699 | security_skb_classify_flow(skb, &fl); | ||
694 | 700 | ||
695 | if (!ip6_dst_lookup(NULL, &buff->dst, &fl)) { | 701 | if (!ip6_dst_lookup(NULL, &buff->dst, &fl)) { |
696 | if (xfrm_lookup(&buff->dst, &fl, NULL, 0) >= 0) { | 702 | if (xfrm_lookup(&buff->dst, &fl, NULL, 0) >= 0) { |
@@ -923,6 +929,7 @@ static struct sock * tcp_v6_syn_recv_sock(struct sock *sk, struct sk_buff *skb, | |||
923 | fl.oif = sk->sk_bound_dev_if; | 929 | fl.oif = sk->sk_bound_dev_if; |
924 | fl.fl_ip_dport = inet_rsk(req)->rmt_port; | 930 | fl.fl_ip_dport = inet_rsk(req)->rmt_port; |
925 | fl.fl_ip_sport = inet_sk(sk)->sport; | 931 | fl.fl_ip_sport = inet_sk(sk)->sport; |
932 | security_sk_classify_flow(sk, &fl); | ||
926 | 933 | ||
927 | if (ip6_dst_lookup(sk, &dst, &fl)) | 934 | if (ip6_dst_lookup(sk, &dst, &fl)) |
928 | goto out; | 935 | goto out; |
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c index 3d54f246411e..82c7c9cde2a8 100644 --- a/net/ipv6/udp.c +++ b/net/ipv6/udp.c | |||
@@ -782,6 +782,8 @@ do_udp_sendmsg: | |||
782 | connected = 0; | 782 | connected = 0; |
783 | } | 783 | } |
784 | 784 | ||
785 | security_sk_classify_flow(sk, fl); | ||
786 | |||
785 | err = ip6_sk_dst_lookup(sk, &dst, fl); | 787 | err = ip6_sk_dst_lookup(sk, &dst, fl); |
786 | if (err) | 788 | if (err) |
787 | goto out; | 789 | goto out; |
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c index 79405daadc52..32c963c90573 100644 --- a/net/xfrm/xfrm_policy.c +++ b/net/xfrm/xfrm_policy.c | |||
@@ -863,7 +863,6 @@ int xfrm_lookup(struct dst_entry **dst_p, struct flowi *fl, | |||
863 | u16 family; | 863 | u16 family; |
864 | u8 dir = policy_to_flow_dir(XFRM_POLICY_OUT); | 864 | u8 dir = policy_to_flow_dir(XFRM_POLICY_OUT); |
865 | 865 | ||
866 | fl->secid = security_sk_sid(sk, fl, dir); | ||
867 | restart: | 866 | restart: |
868 | genid = atomic_read(&flow_cache_genid); | 867 | genid = atomic_read(&flow_cache_genid); |
869 | policy = NULL; | 868 | policy = NULL; |
@@ -1039,7 +1038,7 @@ xfrm_decode_session(struct sk_buff *skb, struct flowi *fl, unsigned short family | |||
1039 | return -EAFNOSUPPORT; | 1038 | return -EAFNOSUPPORT; |
1040 | 1039 | ||
1041 | afinfo->decode_session(skb, fl); | 1040 | afinfo->decode_session(skb, fl); |
1042 | err = security_xfrm_decode_session(skb, fl); | 1041 | err = security_xfrm_decode_session(skb, &fl->secid); |
1043 | xfrm_policy_put_afinfo(afinfo); | 1042 | xfrm_policy_put_afinfo(afinfo); |
1044 | return err; | 1043 | return err; |
1045 | } | 1044 | } |
diff --git a/security/dummy.c b/security/dummy.c index c1f10654871e..c0ff6b9bfd7d 100644 --- a/security/dummy.c +++ b/security/dummy.c | |||
@@ -809,9 +809,8 @@ static inline void dummy_sk_clone_security (const struct sock *sk, struct sock * | |||
809 | { | 809 | { |
810 | } | 810 | } |
811 | 811 | ||
812 | static unsigned int dummy_sk_getsid(struct sock *sk, struct flowi *fl, u8 dir) | 812 | static inline void dummy_sk_getsecid(struct sock *sk, u32 *secid) |
813 | { | 813 | { |
814 | return 0; | ||
815 | } | 814 | } |
816 | #endif /* CONFIG_SECURITY_NETWORK */ | 815 | #endif /* CONFIG_SECURITY_NETWORK */ |
817 | 816 | ||
@@ -866,7 +865,7 @@ static int dummy_xfrm_flow_state_match(struct flowi *fl, struct xfrm_state *xfrm | |||
866 | return 1; | 865 | return 1; |
867 | } | 866 | } |
868 | 867 | ||
869 | static int dummy_xfrm_decode_session(struct sk_buff *skb, struct flowi *fl) | 868 | static int dummy_xfrm_decode_session(struct sk_buff *skb, u32 *fl, int ckall) |
870 | { | 869 | { |
871 | return 0; | 870 | return 0; |
872 | } | 871 | } |
@@ -1083,7 +1082,7 @@ void security_fixup_ops (struct security_operations *ops) | |||
1083 | set_to_dummy_if_null(ops, sk_alloc_security); | 1082 | set_to_dummy_if_null(ops, sk_alloc_security); |
1084 | set_to_dummy_if_null(ops, sk_free_security); | 1083 | set_to_dummy_if_null(ops, sk_free_security); |
1085 | set_to_dummy_if_null(ops, sk_clone_security); | 1084 | set_to_dummy_if_null(ops, sk_clone_security); |
1086 | set_to_dummy_if_null(ops, sk_getsid); | 1085 | set_to_dummy_if_null(ops, sk_getsecid); |
1087 | #endif /* CONFIG_SECURITY_NETWORK */ | 1086 | #endif /* CONFIG_SECURITY_NETWORK */ |
1088 | #ifdef CONFIG_SECURITY_NETWORK_XFRM | 1087 | #ifdef CONFIG_SECURITY_NETWORK_XFRM |
1089 | set_to_dummy_if_null(ops, xfrm_policy_alloc_security); | 1088 | set_to_dummy_if_null(ops, xfrm_policy_alloc_security); |
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 5c189da07bc9..4e5989d584ce 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c | |||
@@ -3561,14 +3561,14 @@ static void selinux_sk_clone_security(const struct sock *sk, struct sock *newsk) | |||
3561 | newssec->peer_sid = ssec->peer_sid; | 3561 | newssec->peer_sid = ssec->peer_sid; |
3562 | } | 3562 | } |
3563 | 3563 | ||
3564 | static unsigned int selinux_sk_getsid_security(struct sock *sk, struct flowi *fl, u8 dir) | 3564 | static void selinux_sk_getsecid(struct sock *sk, u32 *secid) |
3565 | { | 3565 | { |
3566 | if (!sk) | 3566 | if (!sk) |
3567 | return selinux_no_sk_sid(fl); | 3567 | *secid = SECINITSID_ANY_SOCKET; |
3568 | else { | 3568 | else { |
3569 | struct sk_security_struct *sksec = sk->sk_security; | 3569 | struct sk_security_struct *sksec = sk->sk_security; |
3570 | 3570 | ||
3571 | return sksec->sid; | 3571 | *secid = sksec->sid; |
3572 | } | 3572 | } |
3573 | } | 3573 | } |
3574 | 3574 | ||
@@ -4622,7 +4622,7 @@ static struct security_operations selinux_ops = { | |||
4622 | .sk_alloc_security = selinux_sk_alloc_security, | 4622 | .sk_alloc_security = selinux_sk_alloc_security, |
4623 | .sk_free_security = selinux_sk_free_security, | 4623 | .sk_free_security = selinux_sk_free_security, |
4624 | .sk_clone_security = selinux_sk_clone_security, | 4624 | .sk_clone_security = selinux_sk_clone_security, |
4625 | .sk_getsid = selinux_sk_getsid_security, | 4625 | .sk_getsecid = selinux_sk_getsecid, |
4626 | 4626 | ||
4627 | #ifdef CONFIG_SECURITY_NETWORK_XFRM | 4627 | #ifdef CONFIG_SECURITY_NETWORK_XFRM |
4628 | .xfrm_policy_alloc_security = selinux_xfrm_policy_alloc, | 4628 | .xfrm_policy_alloc_security = selinux_xfrm_policy_alloc, |
diff --git a/security/selinux/include/xfrm.h b/security/selinux/include/xfrm.h index f51a3e84bd9b..8e45c1d588a8 100644 --- a/security/selinux/include/xfrm.h +++ b/security/selinux/include/xfrm.h | |||
@@ -19,7 +19,7 @@ int selinux_xfrm_policy_lookup(struct xfrm_policy *xp, u32 fl_secid, u8 dir); | |||
19 | int selinux_xfrm_state_pol_flow_match(struct xfrm_state *x, | 19 | int selinux_xfrm_state_pol_flow_match(struct xfrm_state *x, |
20 | struct xfrm_policy *xp, struct flowi *fl); | 20 | struct xfrm_policy *xp, struct flowi *fl); |
21 | int selinux_xfrm_flow_state_match(struct flowi *fl, struct xfrm_state *xfrm); | 21 | int selinux_xfrm_flow_state_match(struct flowi *fl, struct xfrm_state *xfrm); |
22 | int selinux_xfrm_decode_session(struct sk_buff *skb, struct flowi *fl); | 22 | int selinux_xfrm_decode_session(struct sk_buff *skb, u32 *fl, int ckall); |
23 | 23 | ||
24 | 24 | ||
25 | /* | 25 | /* |
@@ -33,18 +33,6 @@ static inline struct inode_security_struct *get_sock_isec(struct sock *sk) | |||
33 | return SOCK_INODE(sk->sk_socket)->i_security; | 33 | return SOCK_INODE(sk->sk_socket)->i_security; |
34 | } | 34 | } |
35 | 35 | ||
36 | |||
37 | static inline u32 selinux_no_sk_sid(struct flowi *fl) | ||
38 | { | ||
39 | /* NOTE: no sock occurs on ICMP reply, forwards, ... */ | ||
40 | /* icmp_reply: authorize as kernel packet */ | ||
41 | if (fl && fl->proto == IPPROTO_ICMP) { | ||
42 | return SECINITSID_KERNEL; | ||
43 | } | ||
44 | |||
45 | return SECINITSID_ANY_SOCKET; | ||
46 | } | ||
47 | |||
48 | #ifdef CONFIG_SECURITY_NETWORK_XFRM | 36 | #ifdef CONFIG_SECURITY_NETWORK_XFRM |
49 | int selinux_xfrm_sock_rcv_skb(u32 sid, struct sk_buff *skb, | 37 | int selinux_xfrm_sock_rcv_skb(u32 sid, struct sk_buff *skb, |
50 | struct avc_audit_data *ad); | 38 | struct avc_audit_data *ad); |
diff --git a/security/selinux/xfrm.c b/security/selinux/xfrm.c index a502b0540e3d..c750ef7af66f 100644 --- a/security/selinux/xfrm.c +++ b/security/selinux/xfrm.c | |||
@@ -158,11 +158,11 @@ int selinux_xfrm_flow_state_match(struct flowi *fl, struct xfrm_state *xfrm) | |||
158 | * LSM hook implementation that determines the sid for the session. | 158 | * LSM hook implementation that determines the sid for the session. |
159 | */ | 159 | */ |
160 | 160 | ||
161 | int selinux_xfrm_decode_session(struct sk_buff *skb, struct flowi *fl) | 161 | int selinux_xfrm_decode_session(struct sk_buff *skb, u32 *sid, int ckall) |
162 | { | 162 | { |
163 | struct sec_path *sp; | 163 | struct sec_path *sp; |
164 | 164 | ||
165 | fl->secid = SECSID_NULL; | 165 | *sid = SECSID_NULL; |
166 | 166 | ||
167 | if (skb == NULL) | 167 | if (skb == NULL) |
168 | return 0; | 168 | return 0; |
@@ -177,10 +177,13 @@ int selinux_xfrm_decode_session(struct sk_buff *skb, struct flowi *fl) | |||
177 | struct xfrm_sec_ctx *ctx = x->security; | 177 | struct xfrm_sec_ctx *ctx = x->security; |
178 | 178 | ||
179 | if (!sid_set) { | 179 | if (!sid_set) { |
180 | fl->secid = ctx->ctx_sid; | 180 | *sid = ctx->ctx_sid; |
181 | sid_set = 1; | 181 | sid_set = 1; |
182 | |||
183 | if (!ckall) | ||
184 | break; | ||
182 | } | 185 | } |
183 | else if (fl->secid != ctx->ctx_sid) | 186 | else if (*sid != ctx->ctx_sid) |
184 | return -EINVAL; | 187 | return -EINVAL; |
185 | } | 188 | } |
186 | } | 189 | } |