1. 29 May, 2020 1 commit
    • Xin Long's avatar
      xfrm: fix a NULL-ptr deref in xfrm_local_error · f6a23d85
      Xin Long authored
      This patch is to fix a crash:
      
        [ ] kasan: GPF could be caused by NULL-ptr deref or user memory access
        [ ] general protection fault: 0000 [#1] SMP KASAN PTI
        [ ] RIP: 0010:ipv6_local_error+0xac/0x7a0
        [ ] Call Trace:
        [ ]  xfrm6_local_error+0x1eb/0x300
        [ ]  xfrm_local_error+0x95/0x130
        [ ]  __xfrm6_output+0x65f/0xb50
        [ ]  xfrm6_output+0x106/0x46f
        [ ]  udp_tunnel6_xmit_skb+0x618/0xbf0 [ip6_udp_tunnel]
        [ ]  vxlan_xmit_one+0xbc6/0x2c60 [vxlan]
        [ ]  vxlan_xmit+0x6a0/0x4276 [vxlan]
        [ ]  dev_hard_start_xmit+0x165/0x820
        [ ]  __dev_queue_xmit+0x1ff0/0x2b90
        [ ]  ip_finish_output2+0xd3e/0x1480
        [ ]  ip_do_fragment+0x182d/0x2210
        [ ]  ip_output+0x1d0/0x510
        [ ]  ip_send_skb+0x37/0xa0
        [ ]  raw_sendmsg+0x1b4c/0x2b80
        [ ]  sock_sendmsg+0xc0/0x110
      
      This occurred when sending a v4 skb over vxlan6 over ipsec, in which case
      skb->protocol == htons(ETH_P_IPV6) while skb->sk->sk_family == AF_INET in
      xfrm_local_error(). Then it will go to xfrm6_local_error() where it tries
      to get ipv6 info from a ipv4 sk.
      
      This issue was actually fixed by Commit 628e341f ("xfrm: make local
      error reporting more robust"), but brought back by Commit 844d4874
      ("xfrm: choose protocol family by skb protocol").
      
      So to fix it, we should call xfrm6_local_error() only when skb->protocol
      is htons(ETH_P_IPV6) and skb->sk->sk_family is AF_INET6.
      
      Fixes: 844d4874 ("xfrm: choose protocol family by skb protocol")
      Reported-by: default avatarXiumei Mu <xmu@redhat.com>
      Signed-off-by: default avatarXin Long <lucien.xin@gmail.com>
      Signed-off-by: default avatarSteffen Klassert <steffen.klassert@secunet.com>
      f6a23d85
  2. 25 May, 2020 1 commit
    • Xin Long's avatar
      xfrm: fix a warning in xfrm_policy_insert_list · ed17b8d3
      Xin Long authored
      This waring can be triggered simply by:
      
        # ip xfrm policy update src 192.168.1.1/24 dst 192.168.1.2/24 dir in \
          priority 1 mark 0 mask 0x10  #[1]
        # ip xfrm policy update src 192.168.1.1/24 dst 192.168.1.2/24 dir in \
          priority 2 mark 0 mask 0x1   #[2]
        # ip xfrm policy update src 192.168.1.1/24 dst 192.168.1.2/24 dir in \
          priority 2 mark 0 mask 0x10  #[3]
      
      Then dmesg shows:
      
        [ ] WARNING: CPU: 1 PID: 7265 at net/xfrm/xfrm_policy.c:1548
        [ ] RIP: 0010:xfrm_policy_insert_list+0x2f2/0x1030
        [ ] Call Trace:
        [ ]  xfrm_policy_inexact_insert+0x85/0xe50
        [ ]  xfrm_policy_insert+0x4ba/0x680
        [ ]  xfrm_add_policy+0x246/0x4d0
        [ ]  xfrm_user_rcv_msg+0x331/0x5c0
        [ ]  netlink_rcv_skb+0x121/0x350
        [ ]  xfrm_netlink_rcv+0x66/0x80
        [ ]  netlink_unicast+0x439/0x630
        [ ]  netlink_sendmsg+0x714/0xbf0
        [ ]  sock_sendmsg+0xe2/0x110
      
      The issue was introduced by Commit 7cb8a939 ("xfrm: Allow inserting
      policies with matching mark and different priorities"). After that, the
      policies [1] and [2] would be able to be added with different priorities.
      
      However, policy [3] will actually match both [1] and [2]. Policy [1]
      was matched due to the 1st 'return true' in xfrm_policy_mark_match(),
      and policy [2] was matched due to the 2nd 'return true' in there. It
      caused WARN_ON() in xfrm_policy_insert_list().
      
      This patch is to fix it by only (the same value and priority) as the
      same policy in xfrm_policy_mark_match().
      
      Thanks to Yuehaibing, we could make this fix better.
      
      v1->v2:
        - check policy->mark.v == pol->mark.v only without mask.
      
      Fixes: 7cb8a939 ("xfrm: Allow inserting policies with matching mark and different priorities")
      Reported-by: default avatarXiumei Mu <xmu@redhat.com>
      Signed-off-by: default avatarXin Long <lucien.xin@gmail.com>
      Signed-off-by: default avatarSteffen Klassert <steffen.klassert@secunet.com>
      ed17b8d3
  3. 18 May, 2020 1 commit
  4. 14 May, 2020 1 commit
    • Xin Long's avatar
      esp6: calculate transport_header correctly when sel.family != AF_INET6 · 56b1b7c6
      Xin Long authored
      In esp6_init_state() for beet mode when x->sel.family != AF_INET6:
      
        x->props.header_len = sizeof(struct ip_esp_hdr) +
           crypto_aead_ivsize(aead) + IPV4_BEET_PHMAXLEN +
           (sizeof(struct ipv6hdr) - sizeof(struct iphdr))
      
      In xfrm6_beet_gso_segment() skb->transport_header is supposed to move
      to the end of the ph header for IPPROTO_BEETPH, so if x->sel.family !=
      AF_INET6 and it's IPPROTO_BEETPH, it should do:
      
         skb->transport_header -=
            (sizeof(struct ipv6hdr) - sizeof(struct iphdr));
         skb->transport_header += ph->hdrlen * 8;
      
      And IPV4_BEET_PHMAXLEN is only reserved for PH header, so if
      x->sel.family != AF_INET6 and it's not IPPROTO_BEETPH, it should do:
      
         skb->transport_header -=
            (sizeof(struct ipv6hdr) - sizeof(struct iphdr));
         skb->transport_header -= IPV4_BEET_PHMAXLEN;
      
      Thanks Sabrina for looking deep into this issue.
      
      Fixes: 7f9e40eb ("esp6: add gso_segment for esp6 beet mode")
      Reported-by: default avatarSabrina Dubroca <sd@queasysnail.net>
      Signed-off-by: default avatarXin Long <lucien.xin@gmail.com>
      Signed-off-by: default avatarSteffen Klassert <steffen.klassert@secunet.com>
      56b1b7c6
  5. 23 Apr, 2020 2 commits
    • Nicolas Dichtel's avatar
      xfrm interface: fix oops when deleting a x-netns interface · c95c5f58
      Nicolas Dichtel authored
      Here is the steps to reproduce the problem:
      ip netns add foo
      ip netns add bar
      ip -n foo link add xfrmi0 type xfrm dev lo if_id 42
      ip -n foo link set xfrmi0 netns bar
      ip netns del foo
      ip netns del bar
      
      Which results to:
      [  186.686395] general protection fault, probably for non-canonical address 0x6b6b6b6b6b6b6bd3: 0000 [#1] SMP PTI
      [  186.687665] CPU: 7 PID: 232 Comm: kworker/u16:2 Not tainted 5.6.0+ #1
      [  186.688430] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.12.0-1 04/01/2014
      [  186.689420] Workqueue: netns cleanup_net
      [  186.689903] RIP: 0010:xfrmi_dev_uninit+0x1b/0x4b [xfrm_interface]
      [  186.690657] Code: 44 f6 ff ff 31 c0 5b 5d 41 5c 41 5d 41 5e c3 48 8d 8f c0 08 00 00 8b 05 ce 14 00 00 48 8b 97 d0 08 00 00 48 8b 92 c0 0e 00 00 <48> 8b 14 c2 48 8b 02 48 85 c0 74 19 48 39 c1 75 0c 48 8b 87 c0 08
      [  186.692838] RSP: 0018:ffffc900003b7d68 EFLAGS: 00010286
      [  186.693435] RAX: 000000000000000d RBX: ffff8881b0f31000 RCX: ffff8881b0f318c0
      [  186.694334] RDX: 6b6b6b6b6b6b6b6b RSI: 0000000000000246 RDI: ffff8881b0f31000
      [  186.695190] RBP: ffffc900003b7df0 R08: ffff888236c07740 R09: 0000000000000040
      [  186.696024] R10: ffffffff81fce1b8 R11: 0000000000000002 R12: ffffc900003b7d80
      [  186.696859] R13: ffff8881edcc6a40 R14: ffff8881a1b6e780 R15: ffffffff81ed47c8
      [  186.697738] FS:  0000000000000000(0000) GS:ffff888237dc0000(0000) knlGS:0000000000000000
      [  186.698705] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
      [  186.699408] CR2: 00007f2129e93148 CR3: 0000000001e0a000 CR4: 00000000000006e0
      [  186.700221] Call Trace:
      [  186.700508]  rollback_registered_many+0x32b/0x3fd
      [  186.701058]  ? __rtnl_unlock+0x20/0x3d
      [  186.701494]  ? arch_local_irq_save+0x11/0x17
      [  186.702012]  unregister_netdevice_many+0x12/0x55
      [  186.702594]  default_device_exit_batch+0x12b/0x150
      [  186.703160]  ? prepare_to_wait_exclusive+0x60/0x60
      [  186.703719]  cleanup_net+0x17d/0x234
      [  186.704138]  process_one_work+0x196/0x2e8
      [  186.704652]  worker_thread+0x1a4/0x249
      [  186.705087]  ? cancel_delayed_work+0x92/0x92
      [  186.705620]  kthread+0x105/0x10f
      [  186.706000]  ? __kthread_bind_mask+0x57/0x57
      [  186.706501]  ret_from_fork+0x35/0x40
      [  186.706978] Modules linked in: xfrm_interface nfsv3 nfs_acl auth_rpcgss nfsv4 nfs lockd grace fscache sunrpc button parport_pc parport serio_raw evdev pcspkr loop ext4 crc16 mbcache jbd2 crc32c_generic 8139too ide_cd_mod cdrom ide_gd_mod ata_generic ata_piix libata scsi_mod piix psmouse i2c_piix4 ide_core 8139cp i2c_core mii floppy
      [  186.710423] ---[ end trace 463bba18105537e5 ]---
      
      The problem is that x-netns xfrm interface are not removed when the link
      netns is removed. This causes later this oops when thoses interfaces are
      removed.
      
      Let's add a handler to remove all interfaces related to a netns when this
      netns is removed.
      
      Fixes: f203b76d ("xfrm: Add virtual xfrm interfaces")
      Reported-by: default avatarChristophe Gouault <christophe.gouault@6wind.com>
      Signed-off-by: default avatarNicolas Dichtel <nicolas.dichtel@6wind.com>
      Signed-off-by: default avatarSteffen Klassert <steffen.klassert@secunet.com>
      c95c5f58
    • Xin Long's avatar
      ip_vti: receive ipip packet by calling ip_tunnel_rcv · 976eba8a
      Xin Long authored
      In Commit dd9ee344 ("vti4: Fix a ipip packet processing bug in
      'IPCOMP' virtual tunnel"), it tries to receive IPIP packets in vti
      by calling xfrm_input(). This case happens when a small packet or
      frag sent by peer is too small to get compressed.
      
      However, xfrm_input() will still get to the IPCOMP path where skb
      sec_path is set, but never dropped while it should have been done
      in vti_ipcomp4_protocol.cb_handler(vti_rcv_cb), as it's not an
      ipcomp4 packet. This will cause that the packet can never pass
      xfrm4_policy_check() in the upper protocol rcv functions.
      
      So this patch is to call ip_tunnel_rcv() to process IPIP packets
      instead.
      
      Fixes: dd9ee344 ("vti4: Fix a ipip packet processing bug in 'IPCOMP' virtual tunnel")
      Reported-by: default avatarXiumei Mu <xmu@redhat.com>
      Signed-off-by: default avatarXin Long <lucien.xin@gmail.com>
      Signed-off-by: default avatarSteffen Klassert <steffen.klassert@secunet.com>
      976eba8a
  6. 21 Apr, 2020 3 commits
    • Xin Long's avatar
      xfrm: call xfrm_output_gso when inner_protocol is set in xfrm_output · a204aef9
      Xin Long authored
      An use-after-free crash can be triggered when sending big packets over
      vxlan over esp with esp offload enabled:
      
        [] BUG: KASAN: use-after-free in ipv6_gso_pull_exthdrs.part.8+0x32c/0x4e0
        [] Call Trace:
        []  dump_stack+0x75/0xa0
        []  kasan_report+0x37/0x50
        []  ipv6_gso_pull_exthdrs.part.8+0x32c/0x4e0
        []  ipv6_gso_segment+0x2c8/0x13c0
        []  skb_mac_gso_segment+0x1cb/0x420
        []  skb_udp_tunnel_segment+0x6b5/0x1c90
        []  inet_gso_segment+0x440/0x1380
        []  skb_mac_gso_segment+0x1cb/0x420
        []  esp4_gso_segment+0xae8/0x1709 [esp4_offload]
        []  inet_gso_segment+0x440/0x1380
        []  skb_mac_gso_segment+0x1cb/0x420
        []  __skb_gso_segment+0x2d7/0x5f0
        []  validate_xmit_skb+0x527/0xb10
        []  __dev_queue_xmit+0x10f8/0x2320 <---
        []  ip_finish_output2+0xa2e/0x1b50
        []  ip_output+0x1a8/0x2f0
        []  xfrm_output_resume+0x110e/0x15f0
        []  __xfrm4_output+0xe1/0x1b0
        []  xfrm4_output+0xa0/0x200
        []  iptunnel_xmit+0x5a7/0x920
        []  vxlan_xmit_one+0x1658/0x37a0 [vxlan]
        []  vxlan_xmit+0x5e4/0x3ec8 [vxlan]
        []  dev_hard_start_xmit+0x125/0x540
        []  __dev_queue_xmit+0x17bd/0x2320  <---
        []  ip6_finish_output2+0xb20/0x1b80
        []  ip6_output+0x1b3/0x390
        []  ip6_xmit+0xb82/0x17e0
        []  inet6_csk_xmit+0x225/0x3d0
        []  __tcp_transmit_skb+0x1763/0x3520
        []  tcp_write_xmit+0xd64/0x5fe0
        []  __tcp_push_pending_frames+0x8c/0x320
        []  tcp_sendmsg_locked+0x2245/0x3500
        []  tcp_sendmsg+0x27/0x40
      
      As on the tx path of vxlan over esp, skb->inner_network_header would be
      set on vxlan_xmit() and xfrm4_tunnel_encap_add(), and the later one can
      overwrite the former one. It causes skb_udp_tunnel_segment() to use a
      wrong skb->inner_network_header, then the issue occurs.
      
      This patch is to fix it by calling xfrm_output_gso() instead when the
      inner_protocol is set, in which gso_segment of inner_protocol will be
      done first.
      
      While at it, also improve some code around.
      
      Fixes: 7862b405 ("esp: Add gso handlers for esp4 and esp6")
      Reported-by: default avatarXiumei Mu <xmu@redhat.com>
      Signed-off-by: default avatarXin Long <lucien.xin@gmail.com>
      Signed-off-by: default avatarSteffen Klassert <steffen.klassert@secunet.com>
      a204aef9
    • Xin Long's avatar
      esp4: support ipv6 nexthdrs process for beet gso segment · 6f297068
      Xin Long authored
      For beet mode, when it's ipv6 inner address with nexthdrs set,
      the packet format might be:
      
          ----------------------------------------------------
          | outer  |     | dest |     |      |  ESP    | ESP |
          | IP hdr | ESP | opts.| TCP | Data | Trailer | ICV |
          ----------------------------------------------------
      
      Before doing gso segment in xfrm4_beet_gso_segment(), the same
      thing is needed as it does in xfrm6_beet_gso_segment() in last
      patch 'esp6: support ipv6 nexthdrs process for beet gso segment'.
      
      v1->v2:
        - remove skb_transport_offset(), as it will always return 0
          in xfrm6_beet_gso_segment(), thank Sabrina's check.
      
      Fixes: 384a46ea ("esp4: add gso_segment for esp4 beet mode")
      Signed-off-by: default avatarXin Long <lucien.xin@gmail.com>
      Signed-off-by: default avatarSteffen Klassert <steffen.klassert@secunet.com>
      6f297068
    • Xin Long's avatar
      esp6: support ipv6 nexthdrs process for beet gso segment · 25a44ae9
      Xin Long authored
      For beet mode, when it's ipv6 inner address with nexthdrs set,
      the packet format might be:
      
          ----------------------------------------------------
          | outer  |     | dest |     |      |  ESP    | ESP |
          | IP6 hdr| ESP | opts.| TCP | Data | Trailer | ICV |
          ----------------------------------------------------
      
      Before doing gso segment in xfrm6_beet_gso_segment(), it should
      skip all nexthdrs and get the real transport proto, and set
      transport_header properly.
      
      This patch is to fix it by simply calling ipv6_skip_exthdr()
      in xfrm6_beet_gso_segment().
      
      v1->v2:
        - remove skb_transport_offset(), as it will always return 0
          in xfrm6_beet_gso_segment(), thank Sabrina's check.
      
      Fixes: 7f9e40eb ("esp6: add gso_segment for esp6 beet mode")
      Signed-off-by: default avatarXin Long <lucien.xin@gmail.com>
      Signed-off-by: default avatarSteffen Klassert <steffen.klassert@secunet.com>
      25a44ae9
  7. 20 Apr, 2020 3 commits
  8. 15 Apr, 2020 3 commits
    • Xin Long's avatar
      esp6: get the right proto for transport mode in esp6_gso_encap · 3c96ec56
      Xin Long authored
      For transport mode, when ipv6 nexthdr is set, the packet format might
      be like:
      
          ----------------------------------------------------
          |        | dest |     |     |      |  ESP    | ESP |
          | IP6 hdr| opts.| ESP | TCP | Data | Trailer | ICV |
          ----------------------------------------------------
      
      What it wants to get for x-proto in esp6_gso_encap() is the proto that
      will be set in ESP nexthdr. So it should skip all ipv6 nexthdrs and
      get the real transport protocol. Othersize, the wrong proto number
      will be set into ESP nexthdr.
      
      This patch is to skip all ipv6 nexthdrs by calling ipv6_skip_exthdr()
      in esp6_gso_encap().
      
      Fixes: 7862b405 ("esp: Add gso handlers for esp4 and esp6")
      Signed-off-by: default avatarXin Long <lucien.xin@gmail.com>
      Signed-off-by: default avatarSteffen Klassert <steffen.klassert@secunet.com>
      3c96ec56
    • Xin Long's avatar
      xfrm: do pskb_pull properly in __xfrm_transport_prep · 06a0afcf
      Xin Long authored
      For transport mode, when ipv6 nexthdr is set, the packet format might
      be like:
      
          ----------------------------------------------------
          |        | dest |     |     |      |  ESP    | ESP |
          | IP6 hdr| opts.| ESP | TCP | Data | Trailer | ICV |
          ----------------------------------------------------
      
      and in __xfrm_transport_prep():
      
        pskb_pull(skb, skb->mac_len + sizeof(ip6hdr) + x->props.header_len);
      
      it will pull the data pointer to the wrong position, as it missed the
      nexthdrs/dest opts.
      
      This patch is to fix it by using:
      
        pskb_pull(skb, skb_transport_offset(skb) + x->props.header_len);
      
      as we can be sure transport_header points to ESP header at that moment.
      
      It also fixes a panic when packets with ipv6 nexthdr are sent over
      esp6 transport mode:
      
        [  100.473845] kernel BUG at net/core/skbuff.c:4325!
        [  100.478517] RIP: 0010:__skb_to_sgvec+0x252/0x260
        [  100.494355] Call Trace:
        [  100.494829]  skb_to_sgvec+0x11/0x40
        [  100.495492]  esp6_output_tail+0x12e/0x550 [esp6]
        [  100.496358]  esp6_xmit+0x1d5/0x260 [esp6_offload]
        [  100.498029]  validate_xmit_xfrm+0x22f/0x2e0
        [  100.499604]  __dev_queue_xmit+0x589/0x910
        [  100.502928]  ip6_finish_output2+0x2a5/0x5a0
        [  100.503718]  ip6_output+0x6c/0x120
        [  100.505198]  xfrm_output_resume+0x4bf/0x530
        [  100.508683]  xfrm6_output+0x3a/0xc0
        [  100.513446]  inet6_csk_xmit+0xa1/0xf0
        [  100.517335]  tcp_sendmsg+0x27/0x40
        [  100.517977]  sock_sendmsg+0x3e/0x60
        [  100.518648]  __sys_sendto+0xee/0x160
      
      Fixes: c35fe410 ("xfrm: Add mode handlers for IPsec on layer 2")
      Signed-off-by: default avatarXin Long <lucien.xin@gmail.com>
      Signed-off-by: default avatarSteffen Klassert <steffen.klassert@secunet.com>
      06a0afcf
    • Xin Long's avatar
      xfrm: allow to accept packets with ipv6 NEXTHDR_HOP in xfrm_input · afcaf61b
      Xin Long authored
      For beet mode, when it's ipv6 inner address with nexthdrs set,
      the packet format might be:
      
          ----------------------------------------------------
          | outer  |     | dest |     |      |  ESP    | ESP |
          | IP hdr | ESP | opts.| TCP | Data | Trailer | ICV |
          ----------------------------------------------------
      
      The nexthdr from ESP could be NEXTHDR_HOP(0), so it should
      continue processing the packet when nexthdr returns 0 in
      xfrm_input(). Otherwise, when ipv6 nexthdr is set, the
      packet will be dropped.
      
      I don't see any error cases that nexthdr may return 0. So
      fix it by removing the check for nexthdr == 0.
      
      Fixes: 1da177e4 ("Linux-2.6.12-rc2")
      Signed-off-by: default avatarXin Long <lucien.xin@gmail.com>
      Signed-off-by: default avatarSteffen Klassert <steffen.klassert@secunet.com>
      afcaf61b
  9. 14 Apr, 2020 15 commits
  10. 13 Apr, 2020 3 commits
  11. 12 Apr, 2020 3 commits
  12. 11 Apr, 2020 3 commits
  13. 10 Apr, 2020 1 commit
    • David S. Miller's avatar
      Merge git://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf · 40fc7ad2
      David S. Miller authored
      Daniel Borkmann says:
      
      ====================
      pull-request: bpf 2020-04-10
      
      The following pull-request contains BPF updates for your *net* tree.
      
      We've added 13 non-merge commits during the last 7 day(s) which contain
      a total of 13 files changed, 137 insertions(+), 43 deletions(-).
      
      The main changes are:
      
      1) JIT code emission fixes for riscv and arm32, from Luke Nelson and Xi Wang.
      
      2) Disable vmlinux BTF info if GCC_PLUGIN_RANDSTRUCT is used, from Slava Bacherikov.
      
      3) Fix oob write in AF_XDP when meta data is used, from Li RongQing.
      
      4) Fix bpf_get_link_xdp_id() handling on single prog when flags are specified,
         from Andrey Ignatov.
      
      5) Fix sk_assign() BPF helper for request sockets that can have sk_reuseport
         field uninitialized, from Joe Stringer.
      
      6) Fix mprotect() test case for the BPF LSM, from KP Singh.
      ====================
      Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
      40fc7ad2