Merge tag ‘5.1-rc6-smb3-fixes’ of git://git.samba.org/sfrench/cifs-2.6 [Linux 5.1]

Merge tag ‘5.1-rc6-smb3-fixes’ of git://git.samba.org/sfrench/cifs-2.6 [Linux 5.1]

This Linux kernel change "Merge tag ‘5.1-rc6-smb3-fixes’ of git://git.samba.org/sfrench/cifs-2.6" is included in the Linux 5.1 release. This change is authored by Linus Torvalds <torvalds [at] linux-foundation.org> on Fri Apr 26 09:45:39 2019 -0700. The commit for this change in Linux stable tree is 5813023 (patch). Other info about this change: Merge: 8113a85 13f5938

Merge tag '5.1-rc6-smb3-fixes' of git://git.samba.org/sfrench/cifs-2.6

Pull cifs fixes from Steve French:
 "Three small SMB3 fixes (all for stable as well): two leaks and a
  rename bug"

* tag '5.1-rc6-smb3-fixes' of git://git.samba.org/sfrench/cifs-2.6:
  cifs: fix page reference leak with readv/writev
  cifs: do not attempt cifs operation on smb2+ rename error
  cifs: fix memory leak in SMB2_read

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

 net/ipv4/route.c | 32 +++++++++++++++++++++++---------
 1 file changed, 23 insertions(+), 9 deletions(-)

diff --git a/net/ipv4/route.c b/net/ipv4/route.c
index 88ce038..6fdf1c1 100644
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -1183,25 +1183,39 @@ static struct dst_entry *ipv4_dst_check(struct dst_entry *dst, u32 cookie)
    return dst;
 }

-static void ipv4_link_failure(struct sk_buff *skb)
+static void ipv4_send_dest_unreach(struct sk_buff *skb)
 {
    struct ip_options opt;
-   struct rtable *rt;
    int res;

    /* Recompile ip options since IPCB may not be valid anymore.
+    * Also check we have a reasonable ipv4 header.
     */
-   memset(&opt, 0, sizeof(opt));
-   opt.optlen = ip_hdr(skb)->ihl*4 - sizeof(struct iphdr);
+   if (!pskb_network_may_pull(skb, sizeof(struct iphdr)) ||
+       ip_hdr(skb)->version != 4 || ip_hdr(skb)->ihl < 5)
+       return;

-   rcu_read_lock();
-   res = __ip_options_compile(dev_net(skb->dev), &opt, skb, NULL);
-   rcu_read_unlock();
+   memset(&opt, 0, sizeof(opt));
+   if (ip_hdr(skb)->ihl > 5) {
+       if (!pskb_network_may_pull(skb, ip_hdr(skb)->ihl * 4))
+           return;
+       opt.optlen = ip_hdr(skb)->ihl * 4 - sizeof(struct iphdr);

-   if (res)
-       return;
+       rcu_read_lock();
+       res = __ip_options_compile(dev_net(skb->dev), &opt, skb, NULL);
+       rcu_read_unlock();

+       if (res)
+           return;
+   }
    __icmp_send(skb, ICMP_DEST_UNREACH, ICMP_HOST_UNREACH, 0, &opt);
+}
+
+static void ipv4_link_failure(struct sk_buff *skb)
+{
+   struct rtable *rt;
+
+   ipv4_send_dest_unreach(skb);

    rt = skb_rtable(skb);
    if (rt)

Leave a Reply

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