• Xin Long's avatar
    ipv6: do not set sk_destruct in IPV6_ADDRFORM sockopt · e8d411d2
    Xin Long authored
    ChunYu found a kernel warn_on during syzkaller fuzzing:
    
    [40226.038539] WARNING: CPU: 5 PID: 23720 at net/ipv4/af_inet.c:152 inet_sock_destruct+0x78d/0x9a0
    [40226.144849] Call Trace:
    [40226.147590]  <IRQ>
    [40226.149859]  dump_stack+0xe2/0x186
    [40226.176546]  __warn+0x1a4/0x1e0
    [40226.180066]  warn_slowpath_null+0x31/0x40
    [40226.184555]  inet_sock_destruct+0x78d/0x9a0
    [40226.246355]  __sk_destruct+0xfa/0x8c0
    [40226.290612]  rcu_process_callbacks+0xaa0/0x18a0
    [40226.336816]  __do_softirq+0x241/0x75e
    [40226.367758]  irq_exit+0x1f6/0x220
    [40226.371458]  smp_apic_timer_interrupt+0x7b/0xa0
    [40226.376507]  apic_timer_interrupt+0x93/0xa0
    
    The warn_on happned when sk->sk_rmem_alloc wasn't 0 in inet_sock_destruct.
    As after commit f970bd9e ("udp: implement memory accounting helpers"),
    udp has changed to use udp_destruct_sock as sk_destruct where it would
    udp_rmem_release all rmem.
    
    But IPV6_ADDRFORM sockopt sets sk_destruct with inet_sock_destruct after
    changing family to PF_INET. If rmem is not 0 at that time, and there is
    no place to release rmem before calling inet_sock_destruct, the warn_on
    will be triggered.
    
    This patch is to fix it by not setting sk_destruct in IPV6_ADDRFORM sockopt
    any more. As IPV6_ADDRFORM sockopt only works for tcp and udp. TCP sock has
    already set it's sk_destruct with inet_sock_destruct and UDP has set with
    udp_destruct_sock since they're created.
    
    Fixes: f970bd9e ("udp: implement memory accounting helpers")
    Reported-by: default avatarChunYu Wang <chunwang@redhat.com>
    Signed-off-by: default avatarXin Long <lucien.xin@gmail.com>
    Acked-by: default avatarPaolo Abeni <pabeni@redhat.com>
    Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
    e8d411d2
ipv6_sockglue.c 30 KB