• Xin Long's avatar
    sctp: initialize _pad of sockaddr_in before copying to user memory · a7bc830b
    Xin Long authored
    [ Upstream commit 09279e615c81ce55e04835970601ae286e3facbe ]
    
    Syzbot report a kernel-infoleak:
    
      BUG: KMSAN: kernel-infoleak in _copy_to_user+0x16b/0x1f0 lib/usercopy.c:32
      Call Trace:
        _copy_to_user+0x16b/0x1f0 lib/usercopy.c:32
        copy_to_user include/linux/uaccess.h:174 [inline]
        sctp_getsockopt_peer_addrs net/sctp/socket.c:5911 [inline]
        sctp_getsockopt+0x1668e/0x17f70 net/sctp/socket.c:7562
        ...
      Uninit was stored to memory at:
        sctp_transport_init net/sctp/transport.c:61 [inline]
        sctp_transport_new+0x16d/0x9a0 net/sctp/transport.c:115
        sctp_assoc_add_peer+0x532/0x1f70 net/sctp/associola.c:637
        sctp_process_param net/sctp/sm_make_chunk.c:2548 [inline]
        sctp_process_init+0x1a1b/0x3ed0 net/sctp/sm_make_chunk.c:2361
        ...
      Bytes 8-15 of 16 are uninitialized
    
    It was caused by that th _pad field (the 8-15 bytes) of a v4 addr (saved in
    struct sockaddr_in) wasn't initialized, but directly copied to user memory
    in sctp_getsockopt_peer_addrs().
    
    So fix it by calling memset(addr->v4.sin_zero, 0, 8) to initialize _pad of
    sockaddr_in before copying it to user memory in sctp_v4_addr_to_user(), as
    sctp_v6_addr_to_user() does.
    
    Reported-by: syzbot+86b5c7c236a22616a72f@syzkaller.appspotmail.com
    Signed-off-by: 's avatarXin Long <lucien.xin@gmail.com>
    Tested-by: 's avatarAlexander Potapenko <glider@google.com>
    Acked-by: 's avatarNeil Horman <nhorman@tuxdriver.com>
    Signed-off-by: 's avatarDavid S. Miller <davem@davemloft.net>
    Signed-off-by: 's avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
    a7bc830b