lsm,selinux: pass flowi_common instead of flowi to the LSM hooks
authorPaul Moore <paul@paul-moore.com>
Mon, 28 Sep 2020 02:38:26 +0000 (22:38 -0400)
committerPaul Moore <paul@paul-moore.com>
Mon, 23 Nov 2020 23:36:21 +0000 (18:36 -0500)
As pointed out by Herbert in a recent related patch, the LSM hooks do
not have the necessary address family information to use the flowi
struct safely.  As none of the LSMs currently use any of the protocol
specific flowi information, replace the flowi pointers with pointers
to the address family independent flowi_common struct.

Reported-by: Herbert Xu <herbert@gondor.apana.org.au>
Acked-by: James Morris <jamorris@linux.microsoft.com>
Signed-off-by: Paul Moore <paul@paul-moore.com>
33 files changed:
drivers/net/ethernet/chelsio/inline_crypto/chtls/chtls_cm.c
drivers/net/wireguard/socket.c
include/linux/lsm_hook_defs.h
include/linux/lsm_hooks.h
include/linux/security.h
include/net/flow.h
include/net/route.h
net/dccp/ipv4.c
net/dccp/ipv6.c
net/ipv4/icmp.c
net/ipv4/inet_connection_sock.c
net/ipv4/ip_output.c
net/ipv4/ping.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/netfilter/nf_reject_ipv6.c
net/ipv6/ping.c
net/ipv6/raw.c
net/ipv6/syncookies.c
net/ipv6/tcp_ipv6.c
net/ipv6/udp.c
net/l2tp/l2tp_ip6.c
net/netfilter/nf_synproxy_core.c
net/xfrm/xfrm_state.c
security/security.c
security/selinux/hooks.c
security/selinux/include/xfrm.h
security/selinux/xfrm.c

index ec4f79049a061bda7109b686d1525ea238d52f9d..42e4e43cdd918357611b2f3d22c172e8b66ed1ed 100644 (file)
@@ -1148,7 +1148,7 @@ static struct sock *chtls_recv_sock(struct sock *lsk,
                fl6.daddr = ip6h->saddr;
                fl6.fl6_dport = inet_rsk(oreq)->ir_rmt_port;
                fl6.fl6_sport = htons(inet_rsk(oreq)->ir_num);
-               security_req_classify_flow(oreq, flowi6_to_flowi(&fl6));
+               security_req_classify_flow(oreq, flowi6_to_flowi_common(&fl6));
                dst = ip6_dst_lookup_flow(sock_net(lsk), lsk, &fl6, NULL);
                if (IS_ERR(dst))
                        goto free_sk;
index c33e2c81635fa1aaa49ac3b0a917f26e01ac6e2c..410b318e57fb941140fb3e6161eb876fb0d7fa42 100644 (file)
@@ -49,7 +49,7 @@ static int send4(struct wg_device *wg, struct sk_buff *skb,
                rt = dst_cache_get_ip4(cache, &fl.saddr);
 
        if (!rt) {
-               security_sk_classify_flow(sock, flowi4_to_flowi(&fl));
+               security_sk_classify_flow(sock, flowi4_to_flowi_common(&fl));
                if (unlikely(!inet_confirm_addr(sock_net(sock), NULL, 0,
                                                fl.saddr, RT_SCOPE_HOST))) {
                        endpoint->src4.s_addr = 0;
@@ -129,7 +129,7 @@ static int send6(struct wg_device *wg, struct sk_buff *skb,
                dst = dst_cache_get_ip6(cache, &fl.saddr);
 
        if (!dst) {
-               security_sk_classify_flow(sock, flowi6_to_flowi(&fl));
+               security_sk_classify_flow(sock, flowi6_to_flowi_common(&fl));
                if (unlikely(!ipv6_addr_any(&fl.saddr) &&
                             !ipv6_chk_addr(sock_net(sock), &fl.saddr, NULL, 0))) {
                        endpoint->src6 = fl.saddr = in6addr_any;
index 32a940117e7afe4ac997fc19b86684cdb09c0ff7..f70984c8318bce16ac7b9af5e157a90cb94d0096 100644 (file)
@@ -311,7 +311,7 @@ LSM_HOOK(int, 0, secmark_relabel_packet, u32 secid)
 LSM_HOOK(void, LSM_RET_VOID, secmark_refcount_inc, void)
 LSM_HOOK(void, LSM_RET_VOID, secmark_refcount_dec, void)
 LSM_HOOK(void, LSM_RET_VOID, req_classify_flow, const struct request_sock *req,
-        struct flowi *fl)
+        struct flowi_common *flic)
 LSM_HOOK(int, 0, tun_dev_alloc_security, void **security)
 LSM_HOOK(void, LSM_RET_VOID, tun_dev_free_security, void *security)
 LSM_HOOK(int, 0, tun_dev_create, void)
@@ -351,7 +351,7 @@ LSM_HOOK(int, 0, xfrm_state_delete_security, struct xfrm_state *x)
 LSM_HOOK(int, 0, xfrm_policy_lookup, struct xfrm_sec_ctx *ctx, u32 fl_secid,
         u8 dir)
 LSM_HOOK(int, 1, xfrm_state_pol_flow_match, struct xfrm_state *x,
-        struct xfrm_policy *xp, const struct flowi *fl)
+        struct xfrm_policy *xp, const struct flowi_common *flic)
 LSM_HOOK(int, 0, xfrm_decode_session, struct sk_buff *skb, u32 *secid,
         int ckall)
 #endif /* CONFIG_SECURITY_NETWORK_XFRM */
index c503f7ab8afb6b6b2848ec604b319bb66a945133..a19adef1f088809919e49276c29a2fafdd6f5341 100644 (file)
  * @xfrm_state_pol_flow_match:
  *     @x contains the state to match.
  *     @xp contains the policy to check for a match.
- *     @fl contains the flow to check for a match.
+ *     @flic contains the flowi_common struct to check for a match.
  *     Return 1 if there is a match.
  * @xfrm_decode_session:
  *     @skb points to skb to decode.
index bc272549156089a4e92ee7bdc6c86db7343a1f2a..469273e8b46d111e2d3dc99c8975c7243aa0f639 100644 (file)
@@ -167,7 +167,7 @@ struct sk_buff;
 struct sock;
 struct sockaddr;
 struct socket;
-struct flowi;
+struct flowi_common;
 struct dst_entry;
 struct xfrm_selector;
 struct xfrm_policy;
@@ -1355,8 +1355,9 @@ int security_socket_getpeersec_dgram(struct socket *sock, struct sk_buff *skb, u
 int security_sk_alloc(struct sock *sk, int family, gfp_t priority);
 void security_sk_free(struct sock *sk);
 void security_sk_clone(const struct sock *sk, struct sock *newsk);
-void security_sk_classify_flow(struct sock *sk, struct flowi *fl);
-void security_req_classify_flow(const struct request_sock *req, struct flowi *fl);
+void security_sk_classify_flow(struct sock *sk, struct flowi_common *flic);
+void security_req_classify_flow(const struct request_sock *req,
+                               struct flowi_common *flic);
 void security_sock_graft(struct sock*sk, struct socket *parent);
 int security_inet_conn_request(struct sock *sk,
                        struct sk_buff *skb, struct request_sock *req);
@@ -1507,11 +1508,13 @@ static inline void security_sk_clone(const struct sock *sk, struct sock *newsk)
 {
 }
 
-static inline void security_sk_classify_flow(struct sock *sk, struct flowi *fl)
+static inline void security_sk_classify_flow(struct sock *sk,
+                                            struct flowi_common *flic)
 {
 }
 
-static inline void security_req_classify_flow(const struct request_sock *req, struct flowi *fl)
+static inline void security_req_classify_flow(const struct request_sock *req,
+                                             struct flowi_common *flic)
 {
 }
 
@@ -1638,9 +1641,9 @@ void security_xfrm_state_free(struct xfrm_state *x);
 int security_xfrm_policy_lookup(struct xfrm_sec_ctx *ctx, u32 fl_secid, u8 dir);
 int security_xfrm_state_pol_flow_match(struct xfrm_state *x,
                                       struct xfrm_policy *xp,
-                                      const struct flowi *fl);
+                                      const struct flowi_common *flic);
 int security_xfrm_decode_session(struct sk_buff *skb, u32 *secid);
-void security_skb_classify_flow(struct sk_buff *skb, struct flowi *fl);
+void security_skb_classify_flow(struct sk_buff *skb, struct flowi_common *flic);
 
 #else  /* CONFIG_SECURITY_NETWORK_XFRM */
 
@@ -1692,7 +1695,8 @@ static inline int security_xfrm_policy_lookup(struct xfrm_sec_ctx *ctx, u32 fl_s
 }
 
 static inline int security_xfrm_state_pol_flow_match(struct xfrm_state *x,
-                       struct xfrm_policy *xp, const struct flowi *fl)
+                                                    struct xfrm_policy *xp,
+                                                    const struct flowi_common *flic)
 {
        return 1;
 }
@@ -1702,7 +1706,8 @@ 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)
+static inline void security_skb_classify_flow(struct sk_buff *skb,
+                                             struct flowi_common *flic)
 {
 }
 
index b2531df3f65f1958a3fc603a598ee05253b491aa..39d0cedcddeee5eea067596889cd58284f1d4901 100644 (file)
@@ -195,11 +195,21 @@ static inline struct flowi *flowi4_to_flowi(struct flowi4 *fl4)
        return container_of(fl4, struct flowi, u.ip4);
 }
 
+static inline struct flowi_common *flowi4_to_flowi_common(struct flowi4 *fl4)
+{
+       return &(flowi4_to_flowi(fl4)->u.__fl_common);
+}
+
 static inline struct flowi *flowi6_to_flowi(struct flowi6 *fl6)
 {
        return container_of(fl6, struct flowi, u.ip6);
 }
 
+static inline struct flowi_common *flowi6_to_flowi_common(struct flowi6 *fl6)
+{
+       return &(flowi6_to_flowi(fl6)->u.__fl_common);
+}
+
 static inline struct flowi *flowidn_to_flowi(struct flowidn *fldn)
 {
        return container_of(fldn, struct flowi, u.dn);
index ff021cab657e503e7db2044bc7c3309053d6c173..2e6c0e153e3a58b6b28d3af5c166d0aaf5381d53 100644 (file)
@@ -165,7 +165,7 @@ static inline struct rtable *ip_route_output_ports(struct net *net, struct flowi
                           sk ? inet_sk_flowi_flags(sk) : 0,
                           daddr, saddr, dport, sport, sock_net_uid(net, sk));
        if (sk)
-               security_sk_classify_flow(sk, flowi4_to_flowi(fl4));
+               security_sk_classify_flow(sk, flowi4_to_flowi_common(fl4));
        return ip_route_output_flow(net, fl4, sk);
 }
 
@@ -322,7 +322,7 @@ static inline struct rtable *ip_route_connect(struct flowi4 *fl4,
                ip_rt_put(rt);
                flowi4_update_output(fl4, oif, tos, fl4->daddr, fl4->saddr);
        }
-       security_sk_classify_flow(sk, flowi4_to_flowi(fl4));
+       security_sk_classify_flow(sk, flowi4_to_flowi_common(fl4));
        return ip_route_output_flow(net, fl4, sk);
 }
 
@@ -338,7 +338,7 @@ static inline struct rtable *ip_route_newports(struct flowi4 *fl4, struct rtable
                flowi4_update_output(fl4, sk->sk_bound_dev_if,
                                     RT_CONN_FLAGS(sk), fl4->daddr,
                                     fl4->saddr);
-               security_sk_classify_flow(sk, flowi4_to_flowi(fl4));
+               security_sk_classify_flow(sk, flowi4_to_flowi_common(fl4));
                return ip_route_output_flow(sock_net(sk), fl4, sk);
        }
        return rt;
index bb3d70664dde0521091147bc40baf546b2b80c94..3d0b58d7bf3f8dbdf9332296e610ee0e24bfa632 100644 (file)
@@ -464,7 +464,7 @@ static struct dst_entry* dccp_v4_route_skb(struct net *net, struct sock *sk,
                .fl4_dport = dccp_hdr(skb)->dccph_sport,
        };
 
-       security_skb_classify_flow(skb, flowi4_to_flowi(&fl4));
+       security_skb_classify_flow(skb, flowi4_to_flowi_common(&fl4));
        rt = ip_route_output_flow(net, &fl4, sk);
        if (IS_ERR(rt)) {
                IP_INC_STATS(net, IPSTATS_MIB_OUTNOROUTES);
index ef4ab28cfde0e3c1ce9c18550599c7b00bb6de8d..179dcf02a572088c02d7b651bd4a07767f0dcc99 100644 (file)
@@ -203,7 +203,7 @@ static int dccp_v6_send_response(const struct sock *sk, struct request_sock *req
        fl6.flowi6_oif = ireq->ir_iif;
        fl6.fl6_dport = ireq->ir_rmt_port;
        fl6.fl6_sport = htons(ireq->ir_num);
-       security_req_classify_flow(req, flowi6_to_flowi(&fl6));
+       security_req_classify_flow(req, flowi6_to_flowi_common(&fl6));
 
 
        rcu_read_lock();
@@ -279,7 +279,7 @@ static void dccp_v6_ctl_send_reset(const struct sock *sk, struct sk_buff *rxskb)
        fl6.flowi6_oif = inet6_iif(rxskb);
        fl6.fl6_dport = dccp_hdr(skb)->dccph_dport;
        fl6.fl6_sport = dccp_hdr(skb)->dccph_sport;
-       security_skb_classify_flow(rxskb, flowi6_to_flowi(&fl6));
+       security_skb_classify_flow(rxskb, flowi6_to_flowi_common(&fl6));
 
        /* sk = NULL, but it is safe for now. RST socket required. */
        dst = ip6_dst_lookup_flow(sock_net(ctl_sk), ctl_sk, &fl6, NULL);
@@ -907,7 +907,7 @@ static int dccp_v6_connect(struct sock *sk, struct sockaddr *uaddr,
        fl6.flowi6_oif = sk->sk_bound_dev_if;
        fl6.fl6_dport = usin->sin6_port;
        fl6.fl6_sport = inet->inet_sport;
-       security_sk_classify_flow(sk, flowi6_to_flowi(&fl6));
+       security_sk_classify_flow(sk, flowi6_to_flowi_common(&fl6));
 
        opt = rcu_dereference_protected(np->opt, lockdep_sock_is_held(sk));
        final_p = fl6_update_dst(&fl6, opt, &final);
index 005faea415a48ff5c796a983eef7090746e37b49..396b492c804f4f75796b91fd88982162a2eb5dba 100644 (file)
@@ -447,7 +447,7 @@ static void icmp_reply(struct icmp_bxm *icmp_param, struct sk_buff *skb)
        fl4.flowi4_tos = RT_TOS(ip_hdr(skb)->tos);
        fl4.flowi4_proto = IPPROTO_ICMP;
        fl4.flowi4_oif = l3mdev_master_ifindex(skb->dev);
-       security_skb_classify_flow(skb, flowi4_to_flowi(&fl4));
+       security_skb_classify_flow(skb, flowi4_to_flowi_common(&fl4));
        rt = ip_route_output_key(net, &fl4);
        if (IS_ERR(rt))
                goto out_unlock;
@@ -503,7 +503,7 @@ static struct rtable *icmp_route_lookup(struct net *net,
        route_lookup_dev = icmp_get_route_lookup_dev(skb_in);
        fl4->flowi4_oif = l3mdev_master_ifindex(route_lookup_dev);
 
-       security_skb_classify_flow(skb_in, flowi4_to_flowi(fl4));
+       security_skb_classify_flow(skb_in, flowi4_to_flowi_common(fl4));
        rt = ip_route_output_key_hash(net, fl4, skb_in);
        if (IS_ERR(rt))
                return rt;
index 4148f5f78f313cde1e0596b9eb3696df16e3f990..1b7801371f7d1073c2e5d5ce50bc18521fd35413 100644 (file)
@@ -602,7 +602,7 @@ struct dst_entry *inet_csk_route_req(const struct sock *sk,
                           (opt && opt->opt.srr) ? opt->opt.faddr : ireq->ir_rmt_addr,
                           ireq->ir_loc_addr, ireq->ir_rmt_port,
                           htons(ireq->ir_num), sk->sk_uid);
-       security_req_classify_flow(req, flowi4_to_flowi(fl4));
+       security_req_classify_flow(req, flowi4_to_flowi_common(fl4));
        rt = ip_route_output_flow(net, fl4, sk);
        if (IS_ERR(rt))
                goto no_route;
@@ -640,7 +640,7 @@ struct dst_entry *inet_csk_route_child_sock(const struct sock *sk,
                           (opt && opt->opt.srr) ? opt->opt.faddr : ireq->ir_rmt_addr,
                           ireq->ir_loc_addr, ireq->ir_rmt_port,
                           htons(ireq->ir_num), sk->sk_uid);
-       security_req_classify_flow(req, flowi4_to_flowi(fl4));
+       security_req_classify_flow(req, flowi4_to_flowi_common(fl4));
        rt = ip_route_output_flow(net, fl4, sk);
        if (IS_ERR(rt))
                goto no_route;
index 879b76ae4435ca2381170c482a51090d05f3a8b3..89fff5f59eea441c1b016a4576aa3c4e5a204935 100644 (file)
@@ -1700,7 +1700,7 @@ void ip_send_unicast_reply(struct sock *sk, struct sk_buff *skb,
                           daddr, saddr,
                           tcp_hdr(skb)->source, tcp_hdr(skb)->dest,
                           arg->uid);
-       security_skb_classify_flow(skb, flowi4_to_flowi(&fl4));
+       security_skb_classify_flow(skb, flowi4_to_flowi_common(&fl4));
        rt = ip_route_output_key(net, &fl4);
        if (IS_ERR(rt))
                return;
index 248856b301c4570268b006b691889ce9ac74cd09..8b943f85fff9dbb829edcde58ac4906911e8685d 100644 (file)
@@ -778,7 +778,7 @@ static int ping_v4_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
        fl4.fl4_icmp_type = user_icmph.type;
        fl4.fl4_icmp_code = user_icmph.code;
 
-       security_sk_classify_flow(sk, flowi4_to_flowi(&fl4));
+       security_sk_classify_flow(sk, flowi4_to_flowi_common(&fl4));
        rt = ip_route_output_flow(net, &fl4, sk);
        if (IS_ERR(rt)) {
                err = PTR_ERR(rt);
index 7d26e0f8bdaeb5f334e77deb5966a976db3d3ff4..50a73178d63a841a60bf2fdb441b846df775874a 100644 (file)
@@ -640,7 +640,7 @@ static int raw_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
                        goto done;
        }
 
-       security_sk_classify_flow(sk, flowi4_to_flowi(&fl4));
+       security_sk_classify_flow(sk, flowi4_to_flowi_common(&fl4));
        rt = ip_route_output_flow(net, &fl4, sk);
        if (IS_ERR(rt)) {
                err = PTR_ERR(rt);
index 6ac473b47f30d4d5e5e9455424b1a91d84e649ee..36b3b9b72b7559e853f10aa8f6948e93813cf145 100644 (file)
@@ -418,7 +418,7 @@ struct sock *cookie_v4_check(struct sock *sk, struct sk_buff *skb)
                           inet_sk_flowi_flags(sk),
                           opt->srr ? opt->faddr : ireq->ir_rmt_addr,
                           ireq->ir_loc_addr, th->source, th->dest, sk->sk_uid);
-       security_req_classify_flow(req, flowi4_to_flowi(&fl4));
+       security_req_classify_flow(req, flowi4_to_flowi_common(&fl4));
        rt = ip_route_output_key(sock_net(sk), &fl4);
        if (IS_ERR(rt)) {
                reqsk_free(req);
index 09f0a23d1a01741d335ce45f25fe70a4e00698c7..594632ff094f1bc5ef3399f3e565509ec1357730 100644 (file)
@@ -1197,7 +1197,7 @@ int udp_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
                                   faddr, saddr, dport, inet->inet_sport,
                                   sk->sk_uid);
 
-               security_sk_classify_flow(sk, flowi4_to_flowi(fl4));
+               security_sk_classify_flow(sk, flowi4_to_flowi_common(fl4));
                rt = ip_route_output_flow(net, fl4, sk);
                if (IS_ERR(rt)) {
                        err = PTR_ERR(rt);
index e648fbebb1670748de4b22a45356de306a0dc430..b8e491d3acf0709ed06323e50f3bc4425612d1a0 100644 (file)
@@ -819,7 +819,7 @@ int inet6_sk_rebuild_header(struct sock *sk)
                fl6.fl6_dport = inet->inet_dport;
                fl6.fl6_sport = inet->inet_sport;
                fl6.flowi6_uid = sk->sk_uid;
-               security_sk_classify_flow(sk, flowi6_to_flowi(&fl6));
+               security_sk_classify_flow(sk, flowi6_to_flowi_common(&fl6));
 
                rcu_read_lock();
                final_p = fl6_update_dst(&fl6, rcu_dereference(np->opt),
index cc8ad7ddecdaa3537103a501c0745899420af0c6..206f66310a88d1d4e792dadc8e11553781fb6564 100644 (file)
@@ -60,7 +60,7 @@ static void ip6_datagram_flow_key_init(struct flowi6 *fl6, struct sock *sk)
        if (!fl6->flowi6_oif && ipv6_addr_is_multicast(&fl6->daddr))
                fl6->flowi6_oif = np->mcast_oif;
 
-       security_sk_classify_flow(sk, flowi6_to_flowi(fl6));
+       security_sk_classify_flow(sk, flowi6_to_flowi_common(fl6));
 }
 
 int ip6_datagram_dst_update(struct sock *sk, bool fix_sk_saddr)
index ec448b71bf9ae7758c0d85a830bea5a408287e08..91d9136b6e9cf7bb2b4eabc020c84bdc1a3b6619 100644 (file)
@@ -567,7 +567,7 @@ void icmp6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info,
        fl6.fl6_icmp_code = code;
        fl6.flowi6_uid = sock_net_uid(net, NULL);
        fl6.mp_hash = rt6_multipath_hash(net, &fl6, skb, NULL);
-       security_skb_classify_flow(skb, flowi6_to_flowi(&fl6));
+       security_skb_classify_flow(skb, flowi6_to_flowi_common(&fl6));
 
        np = inet6_sk(sk);
 
@@ -749,7 +749,7 @@ static void icmpv6_echo_reply(struct sk_buff *skb)
        fl6.fl6_icmp_type = ICMPV6_ECHO_REPLY;
        fl6.flowi6_mark = mark;
        fl6.flowi6_uid = sock_net_uid(net, NULL);
-       security_skb_classify_flow(skb, flowi6_to_flowi(&fl6));
+       security_skb_classify_flow(skb, flowi6_to_flowi_common(&fl6));
 
        local_bh_disable();
        sk = icmpv6_xmit_lock(net);
@@ -1002,7 +1002,7 @@ void icmpv6_flow_init(struct sock *sk, struct flowi6 *fl6,
        fl6->fl6_icmp_type      = type;
        fl6->fl6_icmp_code      = 0;
        fl6->flowi6_oif         = oif;
-       security_sk_classify_flow(sk, flowi6_to_flowi(fl6));
+       security_sk_classify_flow(sk, flowi6_to_flowi_common(fl6));
 }
 
 static void __net_exit icmpv6_sk_exit(struct net *net)
index e315526fa244ab83363495d4cfa0def7e3decf85..5a9f4d722f35decddba7e06122569a2ea00cd653 100644 (file)
@@ -46,7 +46,7 @@ struct dst_entry *inet6_csk_route_req(const struct sock *sk,
        fl6->fl6_dport = ireq->ir_rmt_port;
        fl6->fl6_sport = htons(ireq->ir_num);
        fl6->flowi6_uid = sk->sk_uid;
-       security_req_classify_flow(req, flowi6_to_flowi(fl6));
+       security_req_classify_flow(req, flowi6_to_flowi_common(fl6));
 
        dst = ip6_dst_lookup_flow(sock_net(sk), sk, fl6, final_p);
        if (IS_ERR(dst))
@@ -95,7 +95,7 @@ static struct dst_entry *inet6_csk_route_socket(struct sock *sk,
        fl6->fl6_sport = inet->inet_sport;
        fl6->fl6_dport = inet->inet_dport;
        fl6->flowi6_uid = sk->sk_uid;
-       security_sk_classify_flow(sk, flowi6_to_flowi(fl6));
+       security_sk_classify_flow(sk, flowi6_to_flowi_common(fl6));
 
        rcu_read_lock();
        final_p = fl6_update_dst(fl6, rcu_dereference(np->opt), &final);
index 4aef6baaa55eba1fab8ca618c03abb5e694426fc..bf95513736c927e847b5d663be26dd3c669b3ad6 100644 (file)
@@ -179,7 +179,7 @@ void nf_send_reset6(struct net *net, struct sk_buff *oldskb, int hook)
 
        fl6.flowi6_oif = l3mdev_master_ifindex(skb_dst(oldskb)->dev);
        fl6.flowi6_mark = IP6_REPLY_MARK(net, oldskb->mark);
-       security_skb_classify_flow(oldskb, flowi6_to_flowi(&fl6));
+       security_skb_classify_flow(oldskb, flowi6_to_flowi_common(&fl6));
        dst = ip6_route_output(net, NULL, &fl6);
        if (dst->error) {
                dst_release(dst);
index 6caa062f68e72b7e3fed6a079b4e58a220ecfff3..6ac88fe24a8e076e59c706413e2241fcf0288260 100644 (file)
@@ -111,7 +111,7 @@ static int ping_v6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
        fl6.flowi6_uid = sk->sk_uid;
        fl6.fl6_icmp_type = user_icmph.icmp6_type;
        fl6.fl6_icmp_code = user_icmph.icmp6_code;
-       security_sk_classify_flow(sk, flowi6_to_flowi(&fl6));
+       security_sk_classify_flow(sk, flowi6_to_flowi_common(&fl6));
 
        ipcm6_init_sk(&ipc6, np);
        ipc6.sockc.mark = sk->sk_mark;
index 6e4ab80a3b94420a85769edf45bbf69e2ba74e39..1f56d9aae5892bc958e19be49d8bcbf544c1d318 100644 (file)
@@ -915,7 +915,7 @@ static int rawv6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
                fl6.flowi6_oif = np->mcast_oif;
        else if (!fl6.flowi6_oif)
                fl6.flowi6_oif = np->ucast_oif;
-       security_sk_classify_flow(sk, flowi6_to_flowi(&fl6));
+       security_sk_classify_flow(sk, flowi6_to_flowi_common(&fl6));
 
        if (hdrincl)
                fl6.flowi6_flags |= FLOWI_FLAG_KNOWN_NH;
index e796a64be308ccf6d1fc2d6c726d3f1763aafb8b..0351e2ffc707f379851ad9c679bd7467fb2fa046 100644 (file)
@@ -233,7 +233,7 @@ struct sock *cookie_v6_check(struct sock *sk, struct sk_buff *skb)
                fl6.fl6_dport = ireq->ir_rmt_port;
                fl6.fl6_sport = inet_sk(sk)->inet_sport;
                fl6.flowi6_uid = sk->sk_uid;
-               security_req_classify_flow(req, flowi6_to_flowi(&fl6));
+               security_req_classify_flow(req, flowi6_to_flowi_common(&fl6));
 
                dst = ip6_dst_lookup_flow(sock_net(sk), sk, &fl6, final_p);
                if (IS_ERR(dst))
index 8db59f4e5f13a99571b26f618100e0f9510b7217..e5f75bbcc66f66ebe3b71897edf1fb7689a641f2 100644 (file)
@@ -278,7 +278,7 @@ static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr,
        opt = rcu_dereference_protected(np->opt, lockdep_sock_is_held(sk));
        final_p = fl6_update_dst(&fl6, opt, &final);
 
-       security_sk_classify_flow(sk, flowi6_to_flowi(&fl6));
+       security_sk_classify_flow(sk, flowi6_to_flowi_common(&fl6));
 
        dst = ip6_dst_lookup_flow(sock_net(sk), sk, &fl6, final_p);
        if (IS_ERR(dst)) {
@@ -954,7 +954,7 @@ static void tcp_v6_send_response(const struct sock *sk, struct sk_buff *skb, u32
        fl6.fl6_dport = t1->dest;
        fl6.fl6_sport = t1->source;
        fl6.flowi6_uid = sock_net_uid(net, sk && sk_fullsock(sk) ? sk : NULL);
-       security_skb_classify_flow(skb, flowi6_to_flowi(&fl6));
+       security_skb_classify_flow(skb, flowi6_to_flowi_common(&fl6));
 
        /* Pass a socket to ip6_dst_lookup either it is for RST
         * Underlying function will use this to retrieve the network
index 29d9691359b9c49ccb56a11f79e3658b1a76700d..724942afc0359147e5effdb4052daac155973792 100644 (file)
@@ -1496,7 +1496,7 @@ do_udp_sendmsg:
        } else if (!fl6.flowi6_oif)
                fl6.flowi6_oif = np->ucast_oif;
 
-       security_sk_classify_flow(sk, flowi6_to_flowi(&fl6));
+       security_sk_classify_flow(sk, flowi6_to_flowi_common(&fl6));
 
        if (ipc6.tclass < 0)
                ipc6.tclass = np->tclass;
index e5e5036257b058af0e0240b6bfa5c2235031f159..96f975777438f7f03614dbfa0c1a978822b0687b 100644 (file)
@@ -606,7 +606,7 @@ static int l2tp_ip6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
        else if (!fl6.flowi6_oif)
                fl6.flowi6_oif = np->ucast_oif;
 
-       security_sk_classify_flow(sk, flowi6_to_flowi(&fl6));
+       security_sk_classify_flow(sk, flowi6_to_flowi_common(&fl6));
 
        if (ipc6.tclass < 0)
                ipc6.tclass = np->tclass;
index 9cca35d22927382e0323cc7cb8cd16913e8d3e87..fb64e8515f7d05f252b13bd1a2e9797703804371 100644 (file)
@@ -849,7 +849,7 @@ synproxy_send_tcp_ipv6(struct net *net,
        fl6.fl6_sport = nth->source;
        fl6.fl6_dport = nth->dest;
        security_skb_classify_flow((struct sk_buff *)skb,
-                                  flowi6_to_flowi(&fl6));
+                                  flowi6_to_flowi_common(&fl6));
        err = nf_ip6_route(net, &dst, flowi6_to_flowi(&fl6), false);
        if (err) {
                goto free_nskb;
index bbd4643d7e824f17d6d9e45e242b000239227b3b..ac25b0c2d87ed5b718dcfe69f6d323dc545dc8a6 100644 (file)
@@ -1021,7 +1021,8 @@ static void xfrm_state_look_at(struct xfrm_policy *pol, struct xfrm_state *x,
                if ((x->sel.family &&
                     (x->sel.family != family ||
                      !xfrm_selector_match(&x->sel, fl, family))) ||
-                   !security_xfrm_state_pol_flow_match(x, pol, fl))
+                   !security_xfrm_state_pol_flow_match(x, pol,
+                                                       &fl->u.__fl_common))
                        return;
 
                if (!*best ||
@@ -1036,7 +1037,8 @@ static void xfrm_state_look_at(struct xfrm_policy *pol, struct xfrm_state *x,
                if ((!x->sel.family ||
                     (x->sel.family == family &&
                      xfrm_selector_match(&x->sel, fl, family))) &&
-                   security_xfrm_state_pol_flow_match(x, pol, fl))
+                   security_xfrm_state_pol_flow_match(x, pol,
+                                                      &fl->u.__fl_common))
                        *error = -ESRCH;
        }
 }
index a28045dc9e7f62b1fe843189b14e7d2f7620c355..c08e0eec8b9ecd4871d3ce4992564db97434f589 100644 (file)
@@ -2207,15 +2207,16 @@ void security_sk_clone(const struct sock *sk, struct sock *newsk)
 }
 EXPORT_SYMBOL(security_sk_clone);
 
-void security_sk_classify_flow(struct sock *sk, struct flowi *fl)
+void security_sk_classify_flow(struct sock *sk, struct flowi_common *flic)
 {
-       call_void_hook(sk_getsecid, sk, &fl->flowi_secid);
+       call_void_hook(sk_getsecid, sk, &flic->flowic_secid);
 }
 EXPORT_SYMBOL(security_sk_classify_flow);
 
-void security_req_classify_flow(const struct request_sock *req, struct flowi *fl)
+void security_req_classify_flow(const struct request_sock *req,
+                               struct flowi_common *flic)
 {
-       call_void_hook(req_classify_flow, req, fl);
+       call_void_hook(req_classify_flow, req, flic);
 }
 EXPORT_SYMBOL(security_req_classify_flow);
 
@@ -2407,7 +2408,7 @@ int security_xfrm_policy_lookup(struct xfrm_sec_ctx *ctx, u32 fl_secid, u8 dir)
 
 int security_xfrm_state_pol_flow_match(struct xfrm_state *x,
                                       struct xfrm_policy *xp,
-                                      const struct flowi *fl)
+                                      const struct flowi_common *flic)
 {
        struct security_hook_list *hp;
        int rc = LSM_RET_DEFAULT(xfrm_state_pol_flow_match);
@@ -2423,7 +2424,7 @@ int security_xfrm_state_pol_flow_match(struct xfrm_state *x,
         */
        hlist_for_each_entry(hp, &security_hook_heads.xfrm_state_pol_flow_match,
                                list) {
-               rc = hp->hook.xfrm_state_pol_flow_match(x, xp, fl);
+               rc = hp->hook.xfrm_state_pol_flow_match(x, xp, flic);
                break;
        }
        return rc;
@@ -2434,9 +2435,9 @@ int security_xfrm_decode_session(struct sk_buff *skb, u32 *secid)
        return call_int_hook(xfrm_decode_session, 0, skb, secid, 1);
 }
 
-void security_skb_classify_flow(struct sk_buff *skb, struct flowi *fl)
+void security_skb_classify_flow(struct sk_buff *skb, struct flowi_common *flic)
 {
-       int rc = call_int_hook(xfrm_decode_session, 0, skb, &fl->flowi_secid,
+       int rc = call_int_hook(xfrm_decode_session, 0, skb, &flic->flowic_secid,
                                0);
 
        BUG_ON(rc);
index 943c2693cec7dcdab26ee33ea86c4d8aa84314cd..a515abdf115b2f162740280ca1a4fc91dae7586a 100644 (file)
@@ -5437,9 +5437,9 @@ static void selinux_secmark_refcount_dec(void)
 }
 
 static void selinux_req_classify_flow(const struct request_sock *req,
-                                     struct flowi *fl)
+                                     struct flowi_common *flic)
 {
-       fl->flowi_secid = req->secid;
+       flic->flowic_secid = req->secid;
 }
 
 static int selinux_tun_dev_alloc_security(void **security)
index a0b46531629228745b5229769a5e92f2eb056704..0a6f34a7a9714359696e9498270b5601ff7416b2 100644 (file)
@@ -26,7 +26,7 @@ int selinux_xfrm_state_delete(struct xfrm_state *x);
 int selinux_xfrm_policy_lookup(struct xfrm_sec_ctx *ctx, u32 fl_secid, u8 dir);
 int selinux_xfrm_state_pol_flow_match(struct xfrm_state *x,
                                      struct xfrm_policy *xp,
-                                     const struct flowi *fl);
+                                     const struct flowi_common *flic);
 
 #ifdef CONFIG_SECURITY_NETWORK_XFRM
 extern atomic_t selinux_xfrm_refcount;
index 7314196185d15f4f357cc2553d860a69af6fe80e..c367d36965d4f6020424761af9aa381ba6ccaca3 100644 (file)
@@ -175,9 +175,10 @@ int selinux_xfrm_policy_lookup(struct xfrm_sec_ctx *ctx, u32 fl_secid, u8 dir)
  */
 int selinux_xfrm_state_pol_flow_match(struct xfrm_state *x,
                                      struct xfrm_policy *xp,
-                                     const struct flowi *fl)
+                                     const struct flowi_common *flic)
 {
        u32 state_sid;
+       u32 flic_sid;
 
        if (!xp->security)
                if (x->security)
@@ -196,17 +197,17 @@ int selinux_xfrm_state_pol_flow_match(struct xfrm_state *x,
                                return 0;
 
        state_sid = x->security->ctx_sid;
+       flic_sid = flic->flowic_secid;
 
-       if (fl->flowi_secid != state_sid)
+       if (flic_sid != state_sid)
                return 0;
 
        /* We don't need a separate SA Vs. policy polmatch check since the SA
         * is now of the same label as the flow and a flow Vs. policy polmatch
         * check had already happened in selinux_xfrm_policy_lookup() above. */
-       return (avc_has_perm(&selinux_state,
-                            fl->flowi_secid, state_sid,
-                           SECCLASS_ASSOCIATION, ASSOCIATION__SENDTO,
-                           NULL) ? 0 : 1);
+       return (avc_has_perm(&selinux_state, flic_sid, state_sid,
+                            SECCLASS_ASSOCIATION, ASSOCIATION__SENDTO,
+                            NULL) ? 0 : 1);
 }
 
 static u32 selinux_xfrm_skb_sid_egress(struct sk_buff *skb)