[MLSXFRM]: Add flow labeling
authorVenkat Yekkirala <vyekkirala@TrustedCS.com>
Sat, 5 Aug 2006 06:12:42 +0000 (23:12 -0700)
committerDavid S. Miller <davem@sunset.davemloft.net>
Fri, 22 Sep 2006 21:53:27 +0000 (14:53 -0700)
This labels the flows that could utilize IPSec xfrms at the points the
flows are defined so that IPSec policy and SAs at the right label can
be used.

The following protos are currently not handled, but they should
continue to be able to use single-labeled IPSec like they currently
do.

ipmr
ip_gre
ipip
igmp
sit
sctp
ip6_tunnel (IPv6 over IPv6 tunnel device)
decnet

Signed-off-by: Venkat Yekkirala <vyekkirala@TrustedCS.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
26 files changed:
include/linux/security.h
include/net/route.h
net/dccp/ipv4.c
net/dccp/ipv6.c
net/ipv4/af_inet.c
net/ipv4/icmp.c
net/ipv4/inet_connection_sock.c
net/ipv4/ip_output.c
net/ipv4/netfilter/ipt_REJECT.c
net/ipv4/raw.c
net/ipv4/syncookies.c
net/ipv4/udp.c
net/ipv6/af_inet6.c
net/ipv6/datagram.c
net/ipv6/icmp.c
net/ipv6/inet6_connection_sock.c
net/ipv6/ndisc.c
net/ipv6/netfilter/ip6t_REJECT.c
net/ipv6/raw.c
net/ipv6/tcp_ipv6.c
net/ipv6/udp.c
net/xfrm/xfrm_policy.c
security/dummy.c
security/selinux/hooks.c
security/selinux/include/xfrm.h
security/selinux/xfrm.c

index 2c4921d79d19b9abe6d50d7b37eef11c4316f656..f3909d189fe0773e291750b0b5422bd7c55a8bf8 100644 (file)
@@ -32,6 +32,7 @@
 #include <linux/sched.h>
 #include <linux/key.h>
 #include <linux/xfrm.h>
+#include <net/flow.h>
 
 struct ctl_table;
 
@@ -815,8 +816,8 @@ struct swap_info_struct;
  *     Deallocate security structure.
  * @sk_clone_security:
  *     Clone/copy security structure.
- * @sk_getsid:
- *     Retrieve the LSM-specific sid for the sock to enable caching of network
+ * @sk_getsecid:
+ *     Retrieve the LSM-specific secid for the sock to enable caching of network
  *     authorizations.
  *
  * Security hooks for XFRM operations.
@@ -882,8 +883,9 @@ struct swap_info_struct;
  *     Return 1 if there is a match.
  * @xfrm_decode_session:
  *     @skb points to skb to decode.
- *     @fl points to the flow key to set.
- *     Return 0 if successful decoding.
+ *     @secid points to the flow key secid to set.
+ *     @ckall says if all xfrms used should be checked for same secid.
+ *     Return 0 if ckall is zero or all xfrms used have the same secid.
  *
  * Security hooks affecting all Key Management operations
  *
@@ -1353,7 +1355,7 @@ struct security_operations {
        int (*sk_alloc_security) (struct sock *sk, int family, gfp_t priority);
        void (*sk_free_security) (struct sock *sk);
        void (*sk_clone_security) (const struct sock *sk, struct sock *newsk);
-       unsigned int (*sk_getsid) (struct sock *sk, struct flowi *fl, u8 dir);
+       void (*sk_getsecid) (struct sock *sk, u32 *secid);
 #endif /* CONFIG_SECURITY_NETWORK */
 
 #ifdef CONFIG_SECURITY_NETWORK_XFRM
@@ -1370,7 +1372,7 @@ struct security_operations {
        int (*xfrm_state_pol_flow_match)(struct xfrm_state *x,
                        struct xfrm_policy *xp, struct flowi *fl);
        int (*xfrm_flow_state_match)(struct flowi *fl, struct xfrm_state *xfrm);
-       int (*xfrm_decode_session)(struct sk_buff *skb, struct flowi *fl);
+       int (*xfrm_decode_session)(struct sk_buff *skb, u32 *secid, int ckall);
 #endif /* CONFIG_SECURITY_NETWORK_XFRM */
 
        /* key management security hooks */
@@ -2917,9 +2919,9 @@ static inline void security_sk_clone(const struct sock *sk, struct sock *newsk)
        return security_ops->sk_clone_security(sk, newsk);
 }
 
-static inline unsigned int security_sk_sid(struct sock *sk, struct flowi *fl, u8 dir)
+static inline void security_sk_classify_flow(struct sock *sk, struct flowi *fl)
 {
-       return security_ops->sk_getsid(sk, fl, dir);
+       security_ops->sk_getsecid(sk, &fl->secid);
 }
 #else  /* CONFIG_SECURITY_NETWORK */
 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)
 {
 }
 
-static inline unsigned int security_sk_sid(struct sock *sk, struct flowi *fl, u8 dir)
+static inline void security_sk_classify_flow(struct sock *sk, struct flowi *fl)
 {
-       return 0;
 }
 #endif /* CONFIG_SECURITY_NETWORK */
 
@@ -3114,9 +3115,16 @@ static inline int security_xfrm_flow_state_match(struct flowi *fl, struct xfrm_s
        return security_ops->xfrm_flow_state_match(fl, xfrm);
 }
 
-static inline int security_xfrm_decode_session(struct sk_buff *skb, struct flowi *fl)
+static inline int security_xfrm_decode_session(struct sk_buff *skb, u32 *secid)
+{
+       return security_ops->xfrm_decode_session(skb, secid, 1);
+}
+
+static inline void security_skb_classify_flow(struct sk_buff *skb, struct flowi *fl)
 {
-       return security_ops->xfrm_decode_session(skb, fl);
+       int rc = security_ops->xfrm_decode_session(skb, &fl->secid, 0);
+
+       BUG_ON(rc);
 }
 #else  /* CONFIG_SECURITY_NETWORK_XFRM */
 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,
        return 1;
 }
 
-static inline int security_xfrm_decode_session(struct sk_buff *skb, struct flowi *fl)
+static inline int security_xfrm_decode_session(struct sk_buff *skb, u32 *secid)
 {
        return 0;
 }
 
+static inline void security_skb_classify_flow(struct sk_buff *skb, struct flowi *fl)
+{
+}
+
 #endif /* CONFIG_SECURITY_NETWORK_XFRM */
 
 #ifdef CONFIG_KEYS
index c4a068692dcc5e0f79ab58e1fd231043b5726236..7f93ac0e089983a0ceed7e4a11c153f2210ce794 100644 (file)
@@ -32,6 +32,7 @@
 #include <linux/route.h>
 #include <linux/ip.h>
 #include <linux/cache.h>
+#include <linux/security.h>
 
 #ifndef __KERNEL__
 #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,
                ip_rt_put(*rp);
                *rp = NULL;
        }
+       security_sk_classify_flow(sk, &fl);
        return ip_route_output_flow(rp, &fl, sk, 0);
 }
 
@@ -182,6 +184,7 @@ static inline int ip_route_newports(struct rtable **rp, u8 protocol,
                fl.proto = protocol;
                ip_rt_put(*rp);
                *rp = NULL;
+               security_sk_classify_flow(sk, &fl);
                return ip_route_output_flow(rp, &fl, sk, 0);
        }
        return 0;
index 7f56f7e8f57169aa77e2a3e49a66514cca5367e7..386498053b1c079a39973cb9b4a7f74640dda052 100644 (file)
@@ -678,6 +678,7 @@ static struct dst_entry* dccp_v4_route_skb(struct sock *sk,
                                     }
                          };
 
+       security_skb_classify_flow(skb, &fl);
        if (ip_route_output_flow(&rt, &fl, sk, 0)) {
                IP_INC_STATS_BH(IPSTATS_MIB_OUTNOROUTES);
                return NULL;
index 610c722ac27f09a7308df128c56caecc0180bb4b..53d255c01431054c5ce8ec54d62772e8ca449537 100644 (file)
@@ -201,6 +201,7 @@ static int dccp_v6_connect(struct sock *sk, struct sockaddr *uaddr,
        fl.oif = sk->sk_bound_dev_if;
        fl.fl_ip_dport = usin->sin6_port;
        fl.fl_ip_sport = inet->sport;
+       security_sk_classify_flow(sk, &fl);
 
        if (np->opt != NULL && np->opt->srcrt != NULL) {
                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,
                        fl.oif = sk->sk_bound_dev_if;
                        fl.fl_ip_dport = inet->dport;
                        fl.fl_ip_sport = inet->sport;
+                       security_sk_classify_flow(sk, &fl);
 
                        err = ip6_dst_lookup(sk, &dst, &fl);
                        if (err) {
@@ -422,6 +424,7 @@ static int dccp_v6_send_response(struct sock *sk, struct request_sock *req,
        fl.oif = ireq6->iif;
        fl.fl_ip_dport = inet_rsk(req)->rmt_port;
        fl.fl_ip_sport = inet_sk(sk)->sport;
+       security_sk_classify_flow(sk, &fl);
 
        if (dst == NULL) {
                opt = np->opt;
@@ -566,6 +569,7 @@ static void dccp_v6_ctl_send_reset(struct sk_buff *rxskb)
        fl.oif = inet6_iif(rxskb);
        fl.fl_ip_dport = dh->dccph_dport;
        fl.fl_ip_sport = dh->dccph_sport;
+       security_skb_classify_flow(rxskb, &fl);
 
        /* sk = NULL, but it is safe for now. RST socket required. */
        if (!ip6_dst_lookup(NULL, &skb->dst, &fl)) {
@@ -622,6 +626,7 @@ static void dccp_v6_reqsk_send_ack(struct sk_buff *rxskb,
        fl.oif = inet6_iif(rxskb);
        fl.fl_ip_dport = dh->dccph_dport;
        fl.fl_ip_sport = dh->dccph_sport;
+       security_skb_classify_flow(rxskb, &fl);
 
        if (!ip6_dst_lookup(NULL, &skb->dst, &fl)) {
                if (xfrm_lookup(&skb->dst, &fl, NULL, 0) >= 0) {
@@ -842,6 +847,7 @@ static struct sock *dccp_v6_request_recv_sock(struct sock *sk,
                fl.oif = sk->sk_bound_dev_if;
                fl.fl_ip_dport = inet_rsk(req)->rmt_port;
                fl.fl_ip_sport = inet_sk(sk)->sport;
+               security_sk_classify_flow(sk, &fl);
 
                if (ip6_dst_lookup(sk, &dst, &fl))
                        goto out;
index c84a32070f8d0dc58ca797e8625942cda0f1d302..fc40da3b6d39994b44cadb415d7eda024999c6f8 100644 (file)
@@ -1074,6 +1074,7 @@ int inet_sk_rebuild_header(struct sock *sk)
                },
        };
                                                
+       security_sk_classify_flow(sk, &fl);
        err = ip_route_output_flow(&rt, &fl, sk, 0);
 }
        if (!err)
index 4c86ac3d882deb0a5f7250714c84f49527cf90c1..6ad797c14163e84356f9c17177a1eb33f2e78da4 100644 (file)
@@ -406,6 +406,7 @@ static void icmp_reply(struct icmp_bxm *icmp_param, struct sk_buff *skb)
                                                .saddr = rt->rt_spec_dst,
                                                .tos = RT_TOS(skb->nh.iph->tos) } },
                                    .proto = IPPROTO_ICMP };
+               security_skb_classify_flow(skb, &fl);
                if (ip_route_output_key(&rt, &fl))
                        goto out_unlock;
        }
@@ -560,6 +561,7 @@ void icmp_send(struct sk_buff *skb_in, int type, int code, u32 info)
                                }
                        }
                };
+               security_skb_classify_flow(skb_in, &fl);
                if (ip_route_output_key(&rt, &fl))
                        goto out_unlock;
        }
index e50a1bfd7ccc2c26306c85e27ffecb2d434c842a..772b4eac78bcb5ab5078bfff296f5cf84dc7b57c 100644 (file)
@@ -327,6 +327,7 @@ struct dst_entry* inet_csk_route_req(struct sock *sk,
                                       { .sport = inet_sk(sk)->sport,
                                         .dport = ireq->rmt_port } } };
 
+       security_sk_classify_flow(sk, &fl);
        if (ip_route_output_flow(&rt, &fl, sk, 0)) {
                IP_INC_STATS_BH(IPSTATS_MIB_OUTNOROUTES);
                return NULL;
index a2ede167e045b32340e3a1346b8ccde641cb6b68..308bdeac3455a4576773f36df761fa7bdda1500e 100644 (file)
@@ -328,6 +328,7 @@ int ip_queue_xmit(struct sk_buff *skb, int ipfragok)
                         * keep trying until route appears or the connection times
                         * itself out.
                         */
+                       security_sk_classify_flow(sk, &fl);
                        if (ip_route_output_flow(&rt, &fl, sk, 0))
                                goto no_route;
                }
@@ -1366,6 +1367,7 @@ void ip_send_reply(struct sock *sk, struct sk_buff *skb, struct ip_reply_arg *ar
                                               { .sport = skb->h.th->dest,
                                                 .dport = skb->h.th->source } },
                                    .proto = sk->sk_protocol };
+               security_skb_classify_flow(skb, &fl);
                if (ip_route_output_key(&rt, &fl))
                        return;
        }
index 269bc2067cb80085588f132703399371468434cf..7f905bf2bde5707fd92d1f42086746707bcc5999 100644 (file)
@@ -90,6 +90,7 @@ static inline struct rtable *route_reverse(struct sk_buff *skb,
        fl.proto = IPPROTO_TCP;
        fl.fl_ip_sport = tcph->dest;
        fl.fl_ip_dport = tcph->source;
+       security_skb_classify_flow(skb, &fl);
 
        xfrm_lookup((struct dst_entry **)&rt, &fl, NULL, 0);
 
index 62b2762a2420bb1331d88d0d076737c1cc358ac3..fe44cb50a1c52cd9b340be552f55abefdc1e5a07 100644 (file)
@@ -484,6 +484,7 @@ static int raw_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
                if (!inet->hdrincl)
                        raw_probe_proto_opt(&fl, msg);
 
+               security_sk_classify_flow(sk, &fl);
                err = ip_route_output_flow(&rt, &fl, sk, !(msg->msg_flags&MSG_DONTWAIT));
        }
        if (err)
index e20be3331f674b14470d1d2b009843f4f6c01747..307dc3c0d635da453e541c9056d60e484cd04b66 100644 (file)
@@ -259,6 +259,7 @@ struct sock *cookie_v4_check(struct sock *sk, struct sk_buff *skb,
                                    .uli_u = { .ports =
                                               { .sport = skb->h.th->dest,
                                                 .dport = skb->h.th->source } } };
+               security_sk_classify_flow(sk, &fl);
                if (ip_route_output_key(&rt, &fl)) {
                        reqsk_free(req);
                        goto out; 
index f136cec96d959c2f94c18078ae35b62a68985099..a4d005eccc7f6668fb5f67abad9d9930fb63f999 100644 (file)
@@ -603,6 +603,7 @@ int udp_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
                                    .uli_u = { .ports =
                                               { .sport = inet->sport,
                                                 .dport = dport } } };
+               security_sk_classify_flow(sk, &fl);
                err = ip_route_output_flow(&rt, &fl, sk, !(msg->msg_flags&MSG_DONTWAIT));
                if (err)
                        goto out;
index ac85e9c532c20aa6c2a6981605a5a26fc211cbb5..82a1b1a328dbfcf6d5ffef44613cd2b7a9870ffc 100644 (file)
@@ -637,6 +637,7 @@ int inet6_sk_rebuild_header(struct sock *sk)
                fl.oif = sk->sk_bound_dev_if;
                fl.fl_ip_dport = inet->dport;
                fl.fl_ip_sport = inet->sport;
+               security_sk_classify_flow(sk, &fl);
 
                if (np->opt && np->opt->srcrt) {
                        struct rt0_hdr *rt0 = (struct rt0_hdr *) np->opt->srcrt;
index 3b55b4c8e2d1814f0bfe43210491efa8497d9813..c73508e090a647f60b449c490dc9b9f51586bcb6 100644 (file)
@@ -156,6 +156,8 @@ ipv4_connected:
        if (!fl.oif && (addr_type&IPV6_ADDR_MULTICAST))
                fl.oif = np->mcast_oif;
 
+       security_sk_classify_flow(sk, &fl);
+
        if (flowlabel) {
                if (flowlabel->opt && flowlabel->opt->srcrt) {
                        struct rt0_hdr *rt0 = (struct rt0_hdr *) flowlabel->opt->srcrt;
index 356a8a7ef22af64833f432cd404d13474811fca4..dbfce089e916d4088788fc00ccef432395390e93 100644 (file)
@@ -358,6 +358,7 @@ void icmpv6_send(struct sk_buff *skb, int type, int code, __u32 info,
        fl.oif = iif;
        fl.fl_icmp_type = type;
        fl.fl_icmp_code = code;
+       security_skb_classify_flow(skb, &fl);
 
        if (icmpv6_xmit_lock())
                return;
@@ -472,6 +473,7 @@ static void icmpv6_echo_reply(struct sk_buff *skb)
                ipv6_addr_copy(&fl.fl6_src, saddr);
        fl.oif = skb->dev->ifindex;
        fl.fl_icmp_type = ICMPV6_ECHO_REPLY;
+       security_skb_classify_flow(skb, &fl);
 
        if (icmpv6_xmit_lock())
                return;
index bf491077b822158302efdd22458f64b5a31d5764..7a51a258615d515ac1d5d4abfafbce60fc4ca81a 100644 (file)
@@ -157,6 +157,7 @@ int inet6_csk_xmit(struct sk_buff *skb, int ipfragok)
        fl.oif = sk->sk_bound_dev_if;
        fl.fl_ip_sport = inet->sport;
        fl.fl_ip_dport = inet->dport;
+       security_sk_classify_flow(sk, &fl);
 
        if (np->opt && np->opt->srcrt) {
                struct rt0_hdr *rt0 = (struct rt0_hdr *)np->opt->srcrt;
index b50055b9278d8b1bf9752b30ff41ad5e648115d4..67cfc3813c32d049794c34bfc0ecb8ddfa3f1bf4 100644 (file)
@@ -419,6 +419,7 @@ static inline void ndisc_flow_init(struct flowi *fl, u8 type,
        fl->proto               = IPPROTO_ICMPV6;
        fl->fl_icmp_type        = type;
        fl->fl_icmp_code        = 0;
+       security_sk_classify_flow(ndisc_socket->sk, fl);
 }
 
 static void ndisc_send_na(struct net_device *dev, struct neighbour *neigh,
index 8629ba195d2d8ae290ac921518f1905e78f7f34f..c4eba1aeb3233eff2424fa608d36ae329f692430 100644 (file)
@@ -96,6 +96,7 @@ static void send_reset(struct sk_buff *oldskb)
        ipv6_addr_copy(&fl.fl6_dst, &oip6h->saddr);
        fl.fl_ip_sport = otcph.dest;
        fl.fl_ip_dport = otcph.source;
+       security_skb_classify_flow(oldskb, &fl);
        dst = ip6_route_output(NULL, &fl);
        if (dst == NULL)
                return;
index 15b862d8acabc621edde195034cb2b9e72737bfd..d5040e172292eb945fcc57e7d269b7ec848ba66a 100644 (file)
@@ -759,6 +759,7 @@ static int rawv6_sendmsg(struct kiocb *iocb, struct sock *sk,
 
        if (!fl.oif && ipv6_addr_is_multicast(&fl.fl6_dst))
                fl.oif = np->mcast_oif;
+       security_sk_classify_flow(sk, &fl);
 
        err = ip6_dst_lookup(sk, &dst, &fl);
        if (err)
index 802a1a6b103762c8c3639017c295cef86348b8be..46922e57e311c22dc2120db8a2b13e0ce8e7e826 100644 (file)
@@ -251,6 +251,8 @@ static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr,
                final_p = &final;
        }
 
+       security_sk_classify_flow(sk, &fl);
+
        err = ip6_dst_lookup(sk, &dst, &fl);
        if (err)
                goto failure;
@@ -374,6 +376,7 @@ static void tcp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
                        fl.oif = sk->sk_bound_dev_if;
                        fl.fl_ip_dport = inet->dport;
                        fl.fl_ip_sport = inet->sport;
+                       security_skb_classify_flow(skb, &fl);
 
                        if ((err = ip6_dst_lookup(sk, &dst, &fl))) {
                                sk->sk_err_soft = -err;
@@ -467,6 +470,7 @@ static int tcp_v6_send_synack(struct sock *sk, struct request_sock *req,
        fl.oif = treq->iif;
        fl.fl_ip_dport = inet_rsk(req)->rmt_port;
        fl.fl_ip_sport = inet_sk(sk)->sport;
+       security_sk_classify_flow(sk, &fl);
 
        if (dst == NULL) {
                opt = np->opt;
@@ -625,6 +629,7 @@ static void tcp_v6_send_reset(struct sk_buff *skb)
        fl.oif = inet6_iif(skb);
        fl.fl_ip_dport = t1->dest;
        fl.fl_ip_sport = t1->source;
+       security_skb_classify_flow(skb, &fl);
 
        /* sk = NULL, but it is safe for now. RST socket required. */
        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
        fl.oif = inet6_iif(skb);
        fl.fl_ip_dport = t1->dest;
        fl.fl_ip_sport = t1->source;
+       security_skb_classify_flow(skb, &fl);
 
        if (!ip6_dst_lookup(NULL, &buff->dst, &fl)) {
                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,
                fl.oif = sk->sk_bound_dev_if;
                fl.fl_ip_dport = inet_rsk(req)->rmt_port;
                fl.fl_ip_sport = inet_sk(sk)->sport;
+               security_sk_classify_flow(sk, &fl);
 
                if (ip6_dst_lookup(sk, &dst, &fl))
                        goto out;
index 3d54f246411e9da1f1d2be9f8f5d3040828175a2..82c7c9cde2a8653dfa744d3ceac7b3451fa9eb37 100644 (file)
@@ -782,6 +782,8 @@ do_udp_sendmsg:
                connected = 0;
        }
 
+       security_sk_classify_flow(sk, fl);
+
        err = ip6_sk_dst_lookup(sk, &dst, fl);
        if (err)
                goto out;
index 79405daadc52bb13a21a9843722d5a6980abd845..32c963c9057354431f81f934235f2aa2785fe783 100644 (file)
@@ -863,7 +863,6 @@ int xfrm_lookup(struct dst_entry **dst_p, struct flowi *fl,
        u16 family;
        u8 dir = policy_to_flow_dir(XFRM_POLICY_OUT);
 
-       fl->secid = security_sk_sid(sk, fl, dir);
 restart:
        genid = atomic_read(&flow_cache_genid);
        policy = NULL;
@@ -1039,7 +1038,7 @@ xfrm_decode_session(struct sk_buff *skb, struct flowi *fl, unsigned short family
                return -EAFNOSUPPORT;
 
        afinfo->decode_session(skb, fl);
-       err = security_xfrm_decode_session(skb, fl);
+       err = security_xfrm_decode_session(skb, &fl->secid);
        xfrm_policy_put_afinfo(afinfo);
        return err;
 }
index c1f10654871e8b5a0478f0ebbcd6865ee4c003c0..c0ff6b9bfd7dc98b2445523afb0c79b4104e2986 100644 (file)
@@ -809,9 +809,8 @@ static inline void dummy_sk_clone_security (const struct sock *sk, struct sock *
 {
 }
 
-static unsigned int dummy_sk_getsid(struct sock *sk, struct flowi *fl, u8 dir)
+static inline void dummy_sk_getsecid(struct sock *sk, u32 *secid)
 {
-       return 0;
 }
 #endif /* CONFIG_SECURITY_NETWORK */
 
@@ -866,7 +865,7 @@ static int dummy_xfrm_flow_state_match(struct flowi *fl, struct xfrm_state *xfrm
        return 1;
 }
 
-static int dummy_xfrm_decode_session(struct sk_buff *skb, struct flowi *fl)
+static int dummy_xfrm_decode_session(struct sk_buff *skb, u32 *fl, int ckall)
 {
        return 0;
 }
@@ -1083,7 +1082,7 @@ void security_fixup_ops (struct security_operations *ops)
        set_to_dummy_if_null(ops, sk_alloc_security);
        set_to_dummy_if_null(ops, sk_free_security);
        set_to_dummy_if_null(ops, sk_clone_security);
-       set_to_dummy_if_null(ops, sk_getsid);
+       set_to_dummy_if_null(ops, sk_getsecid);
  #endif        /* CONFIG_SECURITY_NETWORK */
 #ifdef  CONFIG_SECURITY_NETWORK_XFRM
        set_to_dummy_if_null(ops, xfrm_policy_alloc_security);
index 5c189da07bc9a78cb116fb981d63227ada434995..4e5989d584ce43dd5baacb99e7094d78d4644942 100644 (file)
@@ -3561,14 +3561,14 @@ static void selinux_sk_clone_security(const struct sock *sk, struct sock *newsk)
        newssec->peer_sid = ssec->peer_sid;
 }
 
-static unsigned int selinux_sk_getsid_security(struct sock *sk, struct flowi *fl, u8 dir)
+static void selinux_sk_getsecid(struct sock *sk, u32 *secid)
 {
        if (!sk)
-               return selinux_no_sk_sid(fl);
+               *secid = SECINITSID_ANY_SOCKET;
        else {
                struct sk_security_struct *sksec = sk->sk_security;
 
-               return sksec->sid;
+               *secid = sksec->sid;
        }
 }
 
@@ -4622,7 +4622,7 @@ static struct security_operations selinux_ops = {
        .sk_alloc_security =            selinux_sk_alloc_security,
        .sk_free_security =             selinux_sk_free_security,
        .sk_clone_security =            selinux_sk_clone_security,
-       .sk_getsid =                    selinux_sk_getsid_security,
+       .sk_getsecid =                  selinux_sk_getsecid,
 
 #ifdef CONFIG_SECURITY_NETWORK_XFRM
        .xfrm_policy_alloc_security =   selinux_xfrm_policy_alloc,
index f51a3e84bd9b2f33ae3332a1025c371f4d184fd1..8e45c1d588a8086fb5679e185a8a487f54b277e7 100644 (file)
@@ -19,7 +19,7 @@ int selinux_xfrm_policy_lookup(struct xfrm_policy *xp, u32 fl_secid, u8 dir);
 int selinux_xfrm_state_pol_flow_match(struct xfrm_state *x,
                        struct xfrm_policy *xp, struct flowi *fl);
 int selinux_xfrm_flow_state_match(struct flowi *fl, struct xfrm_state *xfrm);
-int selinux_xfrm_decode_session(struct sk_buff *skb, struct flowi *fl);
+int selinux_xfrm_decode_session(struct sk_buff *skb, u32 *fl, int ckall);
 
 
 /*
@@ -33,18 +33,6 @@ static inline struct inode_security_struct *get_sock_isec(struct sock *sk)
        return SOCK_INODE(sk->sk_socket)->i_security;
 }
 
-
-static inline u32 selinux_no_sk_sid(struct flowi *fl)
-{
-       /* NOTE: no sock occurs on ICMP reply, forwards, ... */
-       /* icmp_reply: authorize as kernel packet */
-       if (fl && fl->proto == IPPROTO_ICMP) {
-               return SECINITSID_KERNEL;
-       }
-
-       return SECINITSID_ANY_SOCKET;
-}
-
 #ifdef CONFIG_SECURITY_NETWORK_XFRM
 int selinux_xfrm_sock_rcv_skb(u32 sid, struct sk_buff *skb,
                        struct avc_audit_data *ad);
index a502b0540e3d749901d755224f0b8935539519a2..c750ef7af66f0c960c1cd3c6164f39b6dba83386 100644 (file)
@@ -158,11 +158,11 @@ int selinux_xfrm_flow_state_match(struct flowi *fl, struct xfrm_state *xfrm)
  * LSM hook implementation that determines the sid for the session.
  */
 
-int selinux_xfrm_decode_session(struct sk_buff *skb, struct flowi *fl)
+int selinux_xfrm_decode_session(struct sk_buff *skb, u32 *sid, int ckall)
 {
        struct sec_path *sp;
 
-       fl->secid = SECSID_NULL;
+       *sid = SECSID_NULL;
 
        if (skb == NULL)
                return 0;
@@ -177,10 +177,13 @@ int selinux_xfrm_decode_session(struct sk_buff *skb, struct flowi *fl)
                                struct xfrm_sec_ctx *ctx = x->security;
 
                                if (!sid_set) {
-                                       fl->secid = ctx->ctx_sid;
+                                       *sid = ctx->ctx_sid;
                                        sid_set = 1;
+
+                                       if (!ckall)
+                                               break;
                                }
-                               else if (fl->secid != ctx->ctx_sid)
+                               else if (*sid != ctx->ctx_sid)
                                        return -EINVAL;
                        }
                }