1. 02 12月, 2020 1 次提交
    • L
      net/ipv6: propagate user pointer annotation · 9e39394f
      Lukas Bulwahn 提交于
      For IPV6_2292PKTOPTIONS, do_ipv6_getsockopt() stores the user pointer
      optval in the msg_control field of the msghdr.
      
      Hence, sparse rightfully warns at ./net/ipv6/ipv6_sockglue.c:1151:33:
      
        warning: incorrect type in assignment (different address spaces)
            expected void *msg_control
            got char [noderef] __user *optval
      
      Since commit 1f466e1f ("net: cleanly handle kernel vs user buffers for
      ->msg_control"), user pointers shall be stored in the msg_control_user
      field, and kernel pointers in the msg_control field. This allows to
      propagate __user annotations nicely through this struct.
      
      Store optval in msg_control_user to properly record and propagate the
      memory space annotation of this pointer.
      
      Note that msg_control_is_user is set to true, so the key invariant, i.e.,
      use msg_control_user if and only if msg_control_is_user is true, holds.
      
      The msghdr is further used in the six alternative put_cmsg() calls, with
      msg_control_is_user being true, put_cmsg() picks msg_control_user
      preserving the __user annotation and passes that properly to
      copy_to_user().
      
      No functional change. No change in object code.
      Signed-off-by: NLukas Bulwahn <lukas.bulwahn@gmail.com>
      Reviewed-by: NChristoph Hellwig <hch@lst.de>
      Link: https://lore.kernel.org/r/20201127093421.21673-1-lukas.bulwahn@gmail.comSigned-off-by: NJakub Kicinski <kuba@kernel.org>
      9e39394f
  2. 31 7月, 2020 1 次提交
    • C
      ipv6: fix memory leaks on IPV6_ADDRFORM path · 8c0de6e9
      Cong Wang 提交于
      IPV6_ADDRFORM causes resource leaks when converting an IPv6 socket
      to IPv4, particularly struct ipv6_ac_socklist. Similar to
      struct ipv6_mc_socklist, we should just close it on this path.
      
      This bug can be easily reproduced with the following C program:
      
        #include <stdio.h>
        #include <string.h>
        #include <sys/types.h>
        #include <sys/socket.h>
        #include <arpa/inet.h>
      
        int main()
        {
          int s, value;
          struct sockaddr_in6 addr;
          struct ipv6_mreq m6;
      
          s = socket(AF_INET6, SOCK_DGRAM, 0);
          addr.sin6_family = AF_INET6;
          addr.sin6_port = htons(5000);
          inet_pton(AF_INET6, "::ffff:192.168.122.194", &addr.sin6_addr);
          connect(s, (struct sockaddr *)&addr, sizeof(addr));
      
          inet_pton(AF_INET6, "fe80::AAAA", &m6.ipv6mr_multiaddr);
          m6.ipv6mr_interface = 5;
          setsockopt(s, SOL_IPV6, IPV6_JOIN_ANYCAST, &m6, sizeof(m6));
      
          value = AF_INET;
          setsockopt(s, SOL_IPV6, IPV6_ADDRFORM, &value, sizeof(value));
      
          close(s);
          return 0;
        }
      
      Reported-by: ch3332xr@gmail.com
      Fixes: 1da177e4 ("Linux-2.6.12-rc2")
      Signed-off-by: NCong Wang <xiyou.wangcong@gmail.com>
      Signed-off-by: NDavid S. Miller <davem@davemloft.net>
      8c0de6e9
  3. 25 7月, 2020 8 次提交
  4. 20 7月, 2020 6 次提交
  5. 05 6月, 2020 1 次提交
    • A
      seg6: fix seg6_validate_srh() to avoid slab-out-of-bounds · bb986a50
      Ahmed Abdelsalam 提交于
      The seg6_validate_srh() is used to validate SRH for three cases:
      
      case1: SRH of data-plane SRv6 packets to be processed by the Linux kernel.
      Case2: SRH of the netlink message received  from user-space (iproute2)
      Case3: SRH injected into packets through setsockopt
      
      In case1, the SRH can be encoded in the Reduced way (i.e., first SID is
      carried in DA only and not represented as SID in the SRH) and the
      seg6_validate_srh() now handles this case correctly.
      
      In case2 and case3, the SRH shouldn’t be encoded in the Reduced way
      otherwise we lose the first segment (i.e., the first hop).
      
      The current implementation of the seg6_validate_srh() allow SRH of case2
      and case3 to be encoded in the Reduced way. This leads a slab-out-of-bounds
      problem.
      
      This patch verifies SRH of case1, case2 and case3. Allowing case1 to be
      reduced while preventing SRH of case2 and case3 from being reduced .
      
      Reported-by: syzbot+e8c028b62439eac42073@syzkaller.appspotmail.com
      Reported-by: NYueHaibing <yuehaibing@huawei.com>
      Fixes: 0cb7498f ("seg6: fix SRH processing to comply with RFC8754")
      Signed-off-by: NAhmed Abdelsalam <ahabdels@gmail.com>
      Signed-off-by: NDavid S. Miller <davem@davemloft.net>
      bb986a50
  6. 02 6月, 2020 1 次提交
    • H
      ipv6: fix IPV6_ADDRFORM operation logic · 79a1f0cc
      Hangbin Liu 提交于
      Socket option IPV6_ADDRFORM supports UDP/UDPLITE and TCP at present.
      Previously the checking logic looks like:
      if (sk->sk_protocol == IPPROTO_UDP || sk->sk_protocol == IPPROTO_UDPLITE)
      	do_some_check;
      else if (sk->sk_protocol != IPPROTO_TCP)
      	break;
      
      After commit b6f61189 ("ipv6: restrict IPV6_ADDRFORM operation"), TCP
      was blocked as the logic changed to:
      if (sk->sk_protocol == IPPROTO_UDP || sk->sk_protocol == IPPROTO_UDPLITE)
      	do_some_check;
      else if (sk->sk_protocol == IPPROTO_TCP)
      	do_some_check;
      	break;
      else
      	break;
      
      Then after commit 82c9ae44 ("ipv6: fix restrict IPV6_ADDRFORM operation")
      UDP/UDPLITE were blocked as the logic changed to:
      if (sk->sk_protocol == IPPROTO_UDP || sk->sk_protocol == IPPROTO_UDPLITE)
      	do_some_check;
      if (sk->sk_protocol == IPPROTO_TCP)
      	do_some_check;
      
      if (sk->sk_protocol != IPPROTO_TCP)
      	break;
      
      Fix it by using Eric's code and simply remove the break in TCP check, which
      looks like:
      if (sk->sk_protocol == IPPROTO_UDP || sk->sk_protocol == IPPROTO_UDPLITE)
      	do_some_check;
      else if (sk->sk_protocol == IPPROTO_TCP)
      	do_some_check;
      else
      	break;
      
      Fixes: 82c9ae44 ("ipv6: fix restrict IPV6_ADDRFORM operation")
      Signed-off-by: NHangbin Liu <liuhangbin@gmail.com>
      Signed-off-by: NDavid S. Miller <davem@davemloft.net>
      79a1f0cc
  7. 29 5月, 2020 1 次提交
  8. 21 5月, 2020 8 次提交
  9. 14 5月, 2020 1 次提交
  10. 21 4月, 2020 1 次提交
  11. 27 2月, 2020 1 次提交
    • E
      ipv6: restrict IPV6_ADDRFORM operation · b6f61189
      Eric Dumazet 提交于
      IPV6_ADDRFORM is able to transform IPv6 socket to IPv4 one.
      While this operation sounds illogical, we have to support it.
      
      One of the things it does for TCP socket is to switch sk->sk_prot
      to tcp_prot.
      
      We now have other layers playing with sk->sk_prot, so we should make
      sure to not interfere with them.
      
      This patch makes sure sk_prot is the default pointer for TCP IPv6 socket.
      
      syzbot reported :
      BUG: kernel NULL pointer dereference, address: 0000000000000000
      PGD a0113067 P4D a0113067 PUD a8771067 PMD 0
      Oops: 0010 [#1] PREEMPT SMP KASAN
      CPU: 0 PID: 10686 Comm: syz-executor.0 Not tainted 5.6.0-rc2-syzkaller #0
      Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011
      RIP: 0010:0x0
      Code: Bad RIP value.
      RSP: 0018:ffffc9000281fce0 EFLAGS: 00010246
      RAX: 1ffffffff15f48ac RBX: ffffffff8afa4560 RCX: dffffc0000000000
      RDX: 0000000000000000 RSI: 0000000000000000 RDI: ffff8880a69a8f40
      RBP: ffffc9000281fd10 R08: ffffffff86ed9b0c R09: ffffed1014d351f5
      R10: ffffed1014d351f5 R11: 0000000000000000 R12: ffff8880920d3098
      R13: 1ffff1101241a613 R14: ffff8880a69a8f40 R15: 0000000000000000
      FS:  00007f2ae75db700(0000) GS:ffff8880aea00000(0000) knlGS:0000000000000000
      CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
      CR2: ffffffffffffffd6 CR3: 00000000a3b85000 CR4: 00000000001406f0
      DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
      DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
      Call Trace:
       inet_release+0x165/0x1c0 net/ipv4/af_inet.c:427
       __sock_release net/socket.c:605 [inline]
       sock_close+0xe1/0x260 net/socket.c:1283
       __fput+0x2e4/0x740 fs/file_table.c:280
       ____fput+0x15/0x20 fs/file_table.c:313
       task_work_run+0x176/0x1b0 kernel/task_work.c:113
       tracehook_notify_resume include/linux/tracehook.h:188 [inline]
       exit_to_usermode_loop arch/x86/entry/common.c:164 [inline]
       prepare_exit_to_usermode+0x480/0x5b0 arch/x86/entry/common.c:195
       syscall_return_slowpath+0x113/0x4a0 arch/x86/entry/common.c:278
       do_syscall_64+0x11f/0x1c0 arch/x86/entry/common.c:304
       entry_SYSCALL_64_after_hwframe+0x49/0xbe
      RIP: 0033:0x45c429
      Code: ad b6 fb ff c3 66 2e 0f 1f 84 00 00 00 00 00 66 90 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 0f 83 7b b6 fb ff c3 66 2e 0f 1f 84 00 00 00 00
      RSP: 002b:00007f2ae75dac78 EFLAGS: 00000246 ORIG_RAX: 0000000000000036
      RAX: 0000000000000000 RBX: 00007f2ae75db6d4 RCX: 000000000045c429
      RDX: 0000000000000001 RSI: 000000000000011a RDI: 0000000000000004
      RBP: 000000000076bf20 R08: 0000000000000038 R09: 0000000000000000
      R10: 0000000020000180 R11: 0000000000000246 R12: 00000000ffffffff
      R13: 0000000000000a9d R14: 00000000004ccfb4 R15: 000000000076bf2c
      Modules linked in:
      CR2: 0000000000000000
      ---[ end trace 82567b5207e87bae ]---
      RIP: 0010:0x0
      Code: Bad RIP value.
      RSP: 0018:ffffc9000281fce0 EFLAGS: 00010246
      RAX: 1ffffffff15f48ac RBX: ffffffff8afa4560 RCX: dffffc0000000000
      RDX: 0000000000000000 RSI: 0000000000000000 RDI: ffff8880a69a8f40
      RBP: ffffc9000281fd10 R08: ffffffff86ed9b0c R09: ffffed1014d351f5
      R10: ffffed1014d351f5 R11: 0000000000000000 R12: ffff8880920d3098
      R13: 1ffff1101241a613 R14: ffff8880a69a8f40 R15: 0000000000000000
      FS:  00007f2ae75db700(0000) GS:ffff8880aea00000(0000) knlGS:0000000000000000
      CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
      CR2: ffffffffffffffd6 CR3: 00000000a3b85000 CR4: 00000000001406f0
      DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
      DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
      
      Fixes: 604326b4 ("bpf, sockmap: convert to generic sk_msg interface")
      Signed-off-by: NEric Dumazet <edumazet@google.com>
      Reported-by: syzbot+1938db17e275e85dc328@syzkaller.appspotmail.com
      Cc: Daniel Borkmann <daniel@iogearbox.net>
      Signed-off-by: NDavid S. Miller <davem@davemloft.net>
      b6f61189
  12. 22 11月, 2019 1 次提交
  13. 31 5月, 2019 1 次提交
  14. 26 5月, 2019 1 次提交
  15. 04 3月, 2019 1 次提交
  16. 08 11月, 2018 1 次提交
  17. 13 9月, 2018 1 次提交
    • A
      ipv6: Add sockopt IPV6_MULTICAST_ALL analogue to IP_MULTICAST_ALL · 15033f04
      Andre Naujoks 提交于
      The socket option will be enabled by default to ensure current behaviour
      is not changed. This is the same for the IPv4 version.
      
      A socket bound to in6addr_any and a specific port will receive all traffic
      on that port. Analogue to IP_MULTICAST_ALL, disable this behaviour, if
      one or more multicast groups were joined (using said socket) and only
      pass on multicast traffic from groups, which were explicitly joined via
      this socket.
      
      Without this option disabled a socket (system even) joined to multiple
      multicast groups is very hard to get right. Filtering by destination
      address has to take place in user space to avoid receiving multicast
      traffic from other multicast groups, which might have traffic on the same
      port.
      
      The extension of the IP_MULTICAST_ALL socketoption to just apply to ipv6,
      too, is not done to avoid changing the behaviour of current applications.
      Signed-off-by: NAndre Naujoks <nautsch2@gmail.com>
      Acked-By: NYOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
      Signed-off-by: NDavid S. Miller <davem@davemloft.net>
      15033f04
  18. 17 7月, 2018 1 次提交
    • H
      ipv6/mcast: init as INCLUDE when join SSM INCLUDE group · c7ea20c9
      Hangbin Liu 提交于
      This an IPv6 version patch of "ipv4/igmp: init group mode as INCLUDE when
      join source group". From RFC3810, part 6.1:
      
         If no per-interface state existed for that
         multicast address before the change (i.e., the change consisted of
         creating a new per-interface record), or if no state exists after the
         change (i.e., the change consisted of deleting a per-interface
         record), then the "non-existent" state is considered to have an
         INCLUDE filter mode and an empty source list.
      
      Which means a new multicast group should start with state IN(). Currently,
      for MLDv2 SSM JOIN_SOURCE_GROUP mode, we first call ipv6_sock_mc_join(),
      then ip6_mc_source(), which will trigger a TO_IN() message instead of
      ALLOW().
      
      The issue was exposed by commit a052517a ("net/multicast: should not
      send source list records when have filter mode change"). Before this change,
      we sent both ALLOW(A) and TO_IN(A). Now, we only send TO_IN(A).
      
      Fix it by adding a new parameter to init group mode. Also add some wrapper
      functions to avoid changing too much code.
      
      v1 -> v2:
      In the first version I only cleared the group change record. But this is not
      enough. Because when a new group join, it will init as EXCLUDE and trigger
      a filter mode change in ip/ip6_mc_add_src(), which will clear all source
      addresses sf_crcount. This will prevent early joined address sending state
      change records if multi source addressed joined at the same time.
      
      In v2 patch, I fixed it by directly initializing the mode to INCLUDE for SSM
      JOIN_SOURCE_GROUP. I also split the original patch into two separated patches
      for IPv4 and IPv6.
      
      There is also a difference between v4 and v6 version. For IPv6, when the
      interface goes down and up, we will send correct state change record with
      unspecified IPv6 address (::) with function ipv6_mc_up(). But after DAD is
      completed, we resend the change record TO_IN() in mld_send_initial_cr().
      Fix it by sending ALLOW() for INCLUDE mode in mld_send_initial_cr().
      
      Fixes: a052517a ("net/multicast: should not send source list records when have filter mode change")
      Reviewed-by: NStefano Brivio <sbrivio@redhat.com>
      Signed-off-by: NHangbin Liu <liuhangbin@gmail.com>
      Signed-off-by: NDavid S. Miller <davem@davemloft.net>
      c7ea20c9
  19. 07 7月, 2018 1 次提交
  20. 05 7月, 2018 1 次提交
    • P
      ipv6: make ipv6_renew_options() interrupt/kernel safe · a9ba23d4
      Paul Moore 提交于
      At present the ipv6_renew_options_kern() function ends up calling into
      access_ok() which is problematic if done from inside an interrupt as
      access_ok() calls WARN_ON_IN_IRQ() on some (all?) architectures
      (x86-64 is affected).  Example warning/backtrace is shown below:
      
       WARNING: CPU: 1 PID: 3144 at lib/usercopy.c:11 _copy_from_user+0x85/0x90
       ...
       Call Trace:
        <IRQ>
        ipv6_renew_option+0xb2/0xf0
        ipv6_renew_options+0x26a/0x340
        ipv6_renew_options_kern+0x2c/0x40
        calipso_req_setattr+0x72/0xe0
        netlbl_req_setattr+0x126/0x1b0
        selinux_netlbl_inet_conn_request+0x80/0x100
        selinux_inet_conn_request+0x6d/0xb0
        security_inet_conn_request+0x32/0x50
        tcp_conn_request+0x35f/0xe00
        ? __lock_acquire+0x250/0x16c0
        ? selinux_socket_sock_rcv_skb+0x1ae/0x210
        ? tcp_rcv_state_process+0x289/0x106b
        tcp_rcv_state_process+0x289/0x106b
        ? tcp_v6_do_rcv+0x1a7/0x3c0
        tcp_v6_do_rcv+0x1a7/0x3c0
        tcp_v6_rcv+0xc82/0xcf0
        ip6_input_finish+0x10d/0x690
        ip6_input+0x45/0x1e0
        ? ip6_rcv_finish+0x1d0/0x1d0
        ipv6_rcv+0x32b/0x880
        ? ip6_make_skb+0x1e0/0x1e0
        __netif_receive_skb_core+0x6f2/0xdf0
        ? process_backlog+0x85/0x250
        ? process_backlog+0x85/0x250
        ? process_backlog+0xec/0x250
        process_backlog+0xec/0x250
        net_rx_action+0x153/0x480
        __do_softirq+0xd9/0x4f7
        do_softirq_own_stack+0x2a/0x40
        </IRQ>
        ...
      
      While not present in the backtrace, ipv6_renew_option() ends up calling
      access_ok() via the following chain:
      
        access_ok()
        _copy_from_user()
        copy_from_user()
        ipv6_renew_option()
      
      The fix presented in this patch is to perform the userspace copy
      earlier in the call chain such that it is only called when the option
      data is actually coming from userspace; that place is
      do_ipv6_setsockopt().  Not only does this solve the problem seen in
      the backtrace above, it also allows us to simplify the code quite a
      bit by removing ipv6_renew_options_kern() completely.  We also take
      this opportunity to cleanup ipv6_renew_options()/ipv6_renew_option()
      a small amount as well.
      
      This patch is heavily based on a rough patch by Al Viro.  I've taken
      his original patch, converted a kmemdup() call in do_ipv6_setsockopt()
      to a memdup_user() call, made better use of the e_inval jump target in
      the same function, and cleaned up the use ipv6_renew_option() by
      ipv6_renew_options().
      
      CC: Al Viro <viro@zeniv.linux.org.uk>
      Signed-off-by: NPaul Moore <paul@paul-moore.com>
      Signed-off-by: NDavid S. Miller <davem@davemloft.net>
      a9ba23d4
  21. 01 3月, 2018 1 次提交