net: bridge: mcast: fix stale ipv6 hdr pointer when handling v6 query [Linux 4.9.187]

This Linux kernel change "net: bridge: mcast: fix stale ipv6 hdr pointer when handling v6 query" is included in the Linux 4.9.187 release. This change is authored by Nikolay Aleksandrov <nikolay [at] cumulusnetworks.com> on Tue Jul 2 15:00:19 2019 +0300. The commit for this change in Linux stable tree is 2aabe0d (patch) which is from upstream commit 3b26a5d. The same Linux upstream change may have been applied to various maintained Linux releases and you can find all Linux releases containing changes from upstream 3b26a5d.

net: bridge: mcast: fix stale ipv6 hdr pointer when handling v6 query

[ Upstream commit 3b26a5d03d35d8f732d75951218983c0f7f68dff ]

We get a pointer to the ipv6 hdr in br_ip6_multicast_query but we may
call pskb_may_pull afterwards and end up using a stale pointer.
So use the header directly, it's just 1 place where it's needed.

Fixes: 08b202b67264 ("bridge br_multicast: IPv6 MLD support.")
Signed-off-by: Nikolay Aleksandrov <nikolay@cumulusnetworks.com>
Tested-by: Martin Weinelt <martin@linuxlounge.net>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

There are 3 lines of Linux source code added/deleted in this change. Code changes to Linux kernel are as follows.

 net/bridge/br_multicast.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/net/bridge/br_multicast.c b/net/bridge/br_multicast.c
index d5fe5fa..3626174 100644
--- a/net/bridge/br_multicast.c
+++ b/net/bridge/br_multicast.c
@@ -1379,7 +1379,6 @@ static int br_ip6_multicast_query(struct net_bridge *br,
                  struct sk_buff *skb,
                  u16 vid)
 {
-   const struct ipv6hdr *ip6h = ipv6_hdr(skb);
    struct mld_msg *mld;
    struct net_bridge_mdb_entry *mp;
    struct mld2_query *mld2q;
@@ -1423,7 +1422,7 @@ static int br_ip6_multicast_query(struct net_bridge *br,

    if (is_general_query) {
        saddr.proto = htons(ETH_P_IPV6);
-       saddr.u.ip6 = ip6h->saddr;
+       saddr.u.ip6 = ipv6_hdr(skb)->saddr;

        br_multicast_query_received(br, port, &br->ip6_other_query,
                        &saddr, max_delay);

Leave a Reply

Your email address will not be published. Required fields are marked *