28 Jul, 2020

6 commits

  • DAN-P (Dual Attached Nodes PRP) nodes are expected to receive
    traditional IP packets as well as PRP (Parallel Redundancy
    Protocol) tagged (trailer) packets. PRP trailer is 6 bytes
    of PRP protocol unit called RCT, Redundancy Control Trailer
    (RCT) similar to HSR tag. PRP network can have traditional
    devices such as bridges/switches or PC attached to it and
    should be able to communicate. Regular Ethernet devices treat
    the RCT as pads. This patch adds logic to format L2 frames
    from network stack to add a trailer (RCT) and send it as
    duplicates over the slave interfaces when the protocol is
    PRP as per IEC 62439-3. At the ingress, it strips the trailer,
    do duplicate detection and rejection and forward a stripped
    frame up the network stack. PRP device should accept frames
    from Singly Attached Nodes (SAN) and thus the driver mark
    the link where the frame came from in the node table.

    Signed-off-by: Murali Karicheri
    Signed-off-by: David S. Miller

    Murali Karicheri
     
  • As a preparatory patch to introduce PRP, refactor the code specific to
    handling HSR frames into separate functions and call them through
    proto_ops function pointers.

    Signed-off-by: Murali Karicheri
    Signed-off-by: David S. Miller

    Murali Karicheri
     
  • Add support for generation of PRP supervision frames. For PRP,
    supervision frame format is similar to HSR version 0, but have
    a PRP Redundancy Control Trailer (RCT) added and uses a different
    message type, PRP_TLV_LIFE_CHECK_DD. Also update
    is_supervision_frame() to include the new message type used for
    PRP supervision frame.

    Signed-off-by: Murali Karicheri
    Signed-off-by: David S. Miller

    Murali Karicheri
     
  • As a preparatory patch to introduce support for PRP protocol, add a
    protocol ops ptr in the private hsr structure to hold function
    pointers as some of the functions at protocol level packet
    handling is different for HSR vs PRP. It is expected that PRP will
    add its of set of functions for protocol handling. Modify existing
    hsr_announce() function to call proto_ops->send_sv_frame() to send
    supervision frame for HSR. This is expected to be different for PRP.
    So introduce a ops function ptr, send_sv_frame() for the same and
    initialize it to send_hsr_supervsion_frame(). Modify hsr_announce()
    to call proto_ops->send_sv_frame().

    Signed-off-by: Murali Karicheri
    Signed-off-by: David S. Miller

    Murali Karicheri
     
  • As a preparatory patch to introduce PRP protocol support in the
    driver, refactor the skb init code to a separate function.

    Signed-off-by: Murali Karicheri
    Signed-off-by: David S. Miller

    Murali Karicheri
     
  • Parallel Redundancy Protocol (PRP) is another redundancy protocol
    introduced by IEC 63439 standard. It is similar to HSR in many
    aspects:-

    - Use a pair of Ethernet interfaces to created the PRP device
    - Use a 6 byte redundancy protocol part (RCT, Redundancy Check
    Trailer) similar to HSR Tag.
    - Has Link Redundancy Entity (LRE) that works with RCT to implement
    redundancy.

    Key difference is that the protocol unit is a trailer instead of a
    prefix as in HSR. That makes it inter-operable with tradition network
    components such as bridges/switches which treat it as pad bytes,
    whereas HSR nodes requires some kind of translators (Called redbox) to
    talk to regular network devices. This features allows regular linux box
    to be converted to a DAN-P box. DAN-P stands for Dual Attached Node - PRP
    similar to DAN-H (Dual Attached Node - HSR).

    Add a comment at the header/source code to explicitly state that the
    driver files also handles PRP protocol as well.

    Signed-off-by: Murali Karicheri
    Signed-off-by: David S. Miller

    Murali Karicheri
     

11 Jul, 2020

1 commit


05 Jul, 2020

1 commit

  • To release hsr(upper) interface, it should release
    its own lower interfaces first.
    Then, hsr(upper) interface can be released safely.
    In the current code of error path of hsr_dev_finalize(), it releases hsr
    interface before releasing a lower interface.
    So, a warning occurs, which warns about the leak of lower interfaces.
    In order to fix this problem, changing the ordering of the error path of
    hsr_dev_finalize() is needed.

    Test commands:
    ip link add dummy0 type dummy
    ip link add dummy1 type dummy
    ip link add dummy2 type dummy
    ip link add hsr0 type hsr slave1 dummy0 slave2 dummy1
    ip link add hsr1 type hsr slave1 dummy2 slave2 dummy0

    Splat looks like:
    [ 214.923127][ C2] WARNING: CPU: 2 PID: 1093 at net/core/dev.c:8992 rollback_registered_many+0x986/0xcf0
    [ 214.923129][ C2] Modules linked in: hsr dummy openvswitch nsh nf_conncount nf_nat nf_conntrack nf_defrag_ipx
    [ 214.923154][ C2] CPU: 2 PID: 1093 Comm: ip Not tainted 5.8.0-rc2+ #623
    [ 214.923156][ C2] Hardware name: innotek GmbH VirtualBox/VirtualBox, BIOS VirtualBox 12/01/2006
    [ 214.923157][ C2] RIP: 0010:rollback_registered_many+0x986/0xcf0
    [ 214.923160][ C2] Code: 41 8b 4e cc 45 31 c0 31 d2 4c 89 ee 48 89 df e8 e0 47 ff ff 85 c0 0f 84 cd fc ff ff 5
    [ 214.923162][ C2] RSP: 0018:ffff8880c5156f28 EFLAGS: 00010287
    [ 214.923165][ C2] RAX: ffff8880d1dad458 RBX: ffff8880bd1b9000 RCX: ffffffffb929d243
    [ 214.923167][ C2] RDX: 1ffffffff77e63f0 RSI: 0000000000000008 RDI: ffffffffbbf31f80
    [ 214.923168][ C2] RBP: dffffc0000000000 R08: fffffbfff77e63f1 R09: fffffbfff77e63f1
    [ 214.923170][ C2] R10: ffffffffbbf31f87 R11: 0000000000000001 R12: ffff8880c51570a0
    [ 214.923172][ C2] R13: ffff8880bd1b90b8 R14: ffff8880c5157048 R15: ffff8880d1dacc40
    [ 214.923174][ C2] FS: 00007fdd257a20c0(0000) GS:ffff8880da200000(0000) knlGS:0000000000000000
    [ 214.923175][ C2] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
    [ 214.923177][ C2] CR2: 00007ffd78beb038 CR3: 00000000be544005 CR4: 00000000000606e0
    [ 214.923179][ C2] Call Trace:
    [ 214.923180][ C2] ? netif_set_real_num_tx_queues+0x780/0x780
    [ 214.923182][ C2] ? dev_validate_mtu+0x140/0x140
    [ 214.923183][ C2] ? synchronize_rcu.part.79+0x85/0xd0
    [ 214.923185][ C2] ? synchronize_rcu_expedited+0xbb0/0xbb0
    [ 214.923187][ C2] rollback_registered+0xc8/0x170
    [ 214.923188][ C2] ? rollback_registered_many+0xcf0/0xcf0
    [ 214.923190][ C2] unregister_netdevice_queue+0x18b/0x240
    [ 214.923191][ C2] hsr_dev_finalize+0x56e/0x6e0 [hsr]
    [ 214.923192][ C2] hsr_newlink+0x36b/0x450 [hsr]
    [ 214.923194][ C2] ? hsr_dellink+0x70/0x70 [hsr]
    [ 214.923195][ C2] ? rtnl_create_link+0x2e4/0xb00
    [ 214.923197][ C2] ? __netlink_ns_capable+0xc3/0xf0
    [ 214.923198][ C2] __rtnl_newlink+0xbdb/0x1270
    [ ... ]

    Fixes: e0a4b99773d3 ("hsr: use upper/lower device infrastructure")
    Reported-by: syzbot+7f1c020f68dab95aab59@syzkaller.appspotmail.com
    Signed-off-by: Taehee Yoo
    Signed-off-by: David S. Miller

    Taehee Yoo
     

29 Jun, 2020

1 commit

  • The method ndo_start_xmit() is defined as returning an 'netdev_tx_t',
    which is a typedef for an enum type, but the implementation in this
    driver returns an 'int'.

    Fix this by returning 'netdev_tx_t' in this driver too.

    Signed-off-by: Luc Van Oostenryck
    Signed-off-by: David S. Miller

    Luc Van Oostenryck
     

23 Jun, 2020

1 commit

  • When an interface is being deleted, "/proc/net/dev_snmp6/"
    is deleted.
    The function for this is addrconf_ifdown() in the addrconf_notify() and
    it is called by notification, which is NETDEV_UNREGISTER.
    But, if NETDEV_CHANGEMTU is triggered after NETDEV_UNREGISTER,
    this proc file will be created again.
    This recreated proc file will be deleted by netdev_wati_allrefs().
    Before netdev_wait_allrefs() is called, creating a new HSR interface
    routine can be executed and It tries to create a proc file but it will
    find an un-deleted proc file.
    At this point, it warns about it.

    To avoid this situation, it can use ->dellink() instead of
    ->ndo_uninit() to release resources because ->dellink() is called
    before NETDEV_UNREGISTER.
    So, a proc file will not be recreated.

    Test commands
    ip link add dummy0 type dummy
    ip link add dummy1 type dummy
    ip link set dummy0 mtu 1300

    #SHELL1
    while :
    do
    ip link add hsr0 type hsr slave1 dummy0 slave2 dummy1
    done

    #SHELL2
    while :
    do
    ip link del hsr0
    done

    Splat looks like:
    [ 9888.980852][ T2752] proc_dir_entry 'dev_snmp6/hsr0' already registered
    [ 9888.981797][ C2] WARNING: CPU: 2 PID: 2752 at fs/proc/generic.c:372 proc_register+0x2d5/0x430
    [ 9888.981798][ C2] Modules linked in: hsr dummy veth openvswitch nsh nf_conncount nf_nat nf_conntrack nf_defrag_ipv6x
    [ 9888.981814][ C2] CPU: 2 PID: 2752 Comm: ip Tainted: G W 5.8.0-rc1+ #616
    [ 9888.981815][ C2] Hardware name: innotek GmbH VirtualBox/VirtualBox, BIOS VirtualBox 12/01/2006
    [ 9888.981816][ C2] RIP: 0010:proc_register+0x2d5/0x430
    [ 9888.981818][ C2] Code: fc ff df 48 89 fa 48 c1 ea 03 80 3c 02 00 0f 85 65 01 00 00 49 8b b5 e0 00 00 00 48 89 ea 40
    [ 9888.981819][ C2] RSP: 0018:ffff8880628dedf0 EFLAGS: 00010286
    [ 9888.981821][ C2] RAX: dffffc0000000008 RBX: ffff888028c69170 RCX: ffffffffaae09a62
    [ 9888.981822][ C2] RDX: 0000000000000001 RSI: 0000000000000008 RDI: ffff88806c9f75ac
    [ 9888.981823][ C2] RBP: ffff888028c693f4 R08: ffffed100d9401bd R09: ffffed100d9401bd
    [ 9888.981824][ C2] R10: ffffffffaddf406f R11: 0000000000000001 R12: ffff888028c69308
    [ 9888.981825][ C2] R13: ffff8880663584c8 R14: dffffc0000000000 R15: ffffed100518d27e
    [ 9888.981827][ C2] FS: 00007f3876b3b0c0(0000) GS:ffff88806c800000(0000) knlGS:0000000000000000
    [ 9888.981828][ C2] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
    [ 9888.981829][ C2] CR2: 00007f387601a8c0 CR3: 000000004101a002 CR4: 00000000000606e0
    [ 9888.981830][ C2] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
    [ 9888.981831][ C2] DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
    [ 9888.981832][ C2] Call Trace:
    [ 9888.981833][ C2] ? snmp6_seq_show+0x180/0x180
    [ 9888.981834][ C2] proc_create_single_data+0x7c/0xa0
    [ 9888.981835][ C2] snmp6_register_dev+0xb0/0x130
    [ 9888.981836][ C2] ipv6_add_dev+0x4b7/0xf60
    [ 9888.981837][ C2] addrconf_notify+0x684/0x1ca0
    [ 9888.981838][ C2] ? __mutex_unlock_slowpath+0xd0/0x670
    [ 9888.981839][ C2] ? kasan_unpoison_shadow+0x30/0x40
    [ 9888.981840][ C2] ? wait_for_completion+0x250/0x250
    [ 9888.981841][ C2] ? inet6_ifinfo_notify+0x100/0x100
    [ 9888.981842][ C2] ? dropmon_net_event+0x227/0x410
    [ 9888.981843][ C2] ? notifier_call_chain+0x90/0x160
    [ 9888.981844][ C2] ? inet6_ifinfo_notify+0x100/0x100
    [ 9888.981845][ C2] notifier_call_chain+0x90/0x160
    [ 9888.981846][ C2] register_netdevice+0xbe5/0x1070
    [ ... ]

    Reported-by: syzbot+1d51c8b74efa4c44adeb@syzkaller.appspotmail.com
    Fixes: e0a4b99773d3 ("hsr: use upper/lower device infrastructure")
    Signed-off-by: Taehee Yoo
    Signed-off-by: David S. Miller

    Taehee Yoo
     

26 Apr, 2020

1 commit


01 Mar, 2020

3 commits

  • netdev_upper_dev_link() is useful to manage lower/upper interfaces.
    And this function internally validates looping, maximum depth.
    All or most virtual interfaces that could have a real interface
    (e.g. macsec, macvlan, ipvlan etc.) use lower/upper infrastructure.

    Signed-off-by: Taehee Yoo
    Signed-off-by: David S. Miller

    Taehee Yoo
     
  • In order to access the port list, the hsr_port_get_hsr() is used.
    And this is protected by RTNL and RCU.
    The hsr_fill_info(), hsr_check_carrier(), hsr_dev_open() and
    hsr_get_max_mtu() are protected by RTNL.
    So, rcu_read_lock() in these functions are not necessary.
    The hsr_handle_frame() also uses rcu_read_lock() but this function
    is called by packet path.
    It's already protected by RCU.
    So, the rcu_read_lock() in hsr_handle_frame() can be removed.

    Signed-off-by: Taehee Yoo
    Signed-off-by: David S. Miller

    Taehee Yoo
     
  • If HSR uses the extack instead of netdev_info(), users can get
    error messages immediately without any checking the kernel message.

    Signed-off-by: Taehee Yoo
    Signed-off-by: David S. Miller

    Taehee Yoo
     

26 Dec, 2019

3 commits

  • The supervision frame is L2 frame.
    When supervision frame is created, hsr module doesn't set network header.
    If tap routine is enabled, dev_queue_xmit_nit() is called and it checks
    network_header. If network_header pointer wasn't set(or invalid),
    it resets network_header and warns.
    In order to avoid unnecessary warning message, resetting network_header
    is needed.

    Test commands:
    ip netns add nst
    ip link add veth0 type veth peer name veth1
    ip link add veth2 type veth peer name veth3
    ip link set veth1 netns nst
    ip link set veth3 netns nst
    ip link set veth0 up
    ip link set veth2 up
    ip link add hsr0 type hsr slave1 veth0 slave2 veth2
    ip a a 192.168.100.1/24 dev hsr0
    ip link set hsr0 up
    ip netns exec nst ip link set veth1 up
    ip netns exec nst ip link set veth3 up
    ip netns exec nst ip link add hsr1 type hsr slave1 veth1 slave2 veth3
    ip netns exec nst ip a a 192.168.100.2/24 dev hsr1
    ip netns exec nst ip link set hsr1 up
    tcpdump -nei veth0

    Splat looks like:
    [ 175.852292][ C3] protocol 88fb is buggy, dev veth0

    Fixes: f421436a591d ("net/hsr: Add support for the High-availability Seamless Redundancy protocol (HSRv0)")
    Signed-off-by: Taehee Yoo
    Signed-off-by: David S. Miller

    Taehee Yoo
     
  • hsr nodes are protected by RCU and there is no write side lock.
    But node insertions and deletions could be being operated concurrently.
    So write side locking is needed.

    Test commands:
    ip netns add nst
    ip link add veth0 type veth peer name veth1
    ip link add veth2 type veth peer name veth3
    ip link set veth1 netns nst
    ip link set veth3 netns nst
    ip link set veth0 up
    ip link set veth2 up
    ip link add hsr0 type hsr slave1 veth0 slave2 veth2
    ip a a 192.168.100.1/24 dev hsr0
    ip link set hsr0 up
    ip netns exec nst ip link set veth1 up
    ip netns exec nst ip link set veth3 up
    ip netns exec nst ip link add hsr1 type hsr slave1 veth1 slave2 veth3
    ip netns exec nst ip a a 192.168.100.2/24 dev hsr1
    ip netns exec nst ip link set hsr1 up

    for i in {0..9}
    do
    for j in {0..9}
    do
    for k in {0..9}
    do
    for l in {0..9}
    do
    arping 192.168.100.2 -I hsr0 -s 00:01:3$i:4$j:5$k:6$l -c1 &
    done
    done
    done
    done

    Splat looks like:
    [ 236.066091][ T3286] list_add corruption. next->prev should be prev (ffff8880a5940300), but was ffff8880a5940d0.
    [ 236.069617][ T3286] ------------[ cut here ]------------
    [ 236.070545][ T3286] kernel BUG at lib/list_debug.c:25!
    [ 236.071391][ T3286] invalid opcode: 0000 [#1] SMP DEBUG_PAGEALLOC KASAN PTI
    [ 236.072343][ T3286] CPU: 0 PID: 3286 Comm: arping Tainted: G W 5.5.0-rc1+ #209
    [ 236.073463][ T3286] Hardware name: innotek GmbH VirtualBox/VirtualBox, BIOS VirtualBox 12/01/2006
    [ 236.074695][ T3286] RIP: 0010:__list_add_valid+0x74/0xd0
    [ 236.075499][ T3286] Code: 48 39 da 75 27 48 39 f5 74 36 48 39 dd 74 31 48 83 c4 08 b8 01 00 00 00 5b 5d c3 48 b
    [ 236.078277][ T3286] RSP: 0018:ffff8880aaa97648 EFLAGS: 00010286
    [ 236.086991][ T3286] RAX: 0000000000000075 RBX: ffff8880d4624c20 RCX: 0000000000000000
    [ 236.088000][ T3286] RDX: 0000000000000075 RSI: 0000000000000008 RDI: ffffed1015552ebf
    [ 236.098897][ T3286] RBP: ffff88809b53d200 R08: ffffed101b3c04f9 R09: ffffed101b3c04f9
    [ 236.099960][ T3286] R10: 00000000308769a1 R11: ffffed101b3c04f8 R12: ffff8880d4624c28
    [ 236.100974][ T3286] R13: ffff8880d4624c20 R14: 0000000040310100 R15: ffff8880ce17ee02
    [ 236.138967][ T3286] FS: 00007f23479fa680(0000) GS:ffff8880d9c00000(0000) knlGS:0000000000000000
    [ 236.144852][ T3286] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
    [ 236.145720][ T3286] CR2: 00007f4a14bab210 CR3: 00000000a61c6001 CR4: 00000000000606f0
    [ 236.146776][ T3286] Call Trace:
    [ 236.147222][ T3286] hsr_add_node+0x314/0x490 [hsr]
    [ 236.153633][ T3286] hsr_forward_skb+0x2b6/0x1bc0 [hsr]
    [ 236.154362][ T3286] ? rcu_read_lock_sched_held+0x90/0xc0
    [ 236.155091][ T3286] ? rcu_read_lock_bh_held+0xa0/0xa0
    [ 236.156607][ T3286] hsr_dev_xmit+0x70/0xd0 [hsr]
    [ 236.157254][ T3286] dev_hard_start_xmit+0x160/0x740
    [ 236.157941][ T3286] __dev_queue_xmit+0x1961/0x2e10
    [ 236.158565][ T3286] ? netdev_core_pick_tx+0x2e0/0x2e0
    [ ... ]

    Reported-by: syzbot+3924327f9ad5f4d2b343@syzkaller.appspotmail.com
    Fixes: f421436a591d ("net/hsr: Add support for the High-availability Seamless Redundancy protocol (HSRv0)")
    Signed-off-by: Taehee Yoo
    Signed-off-by: David S. Miller

    Taehee Yoo
     
  • hsr_dev_finalize() is called to create new hsr interface.
    There are some wrong error handling codes.

    1. wrong checking return value of debugfs_create_{dir/file}.
    These function doesn't return NULL. If error occurs in there,
    it returns error pointer.
    So, it should check error pointer instead of NULL.

    2. It doesn't unregister interface if it fails to setup hsr interface.
    If it fails to initialize hsr interface after register_netdevice(),
    it should call unregister_netdevice().

    3. Ignore failure of creation of debugfs
    If creating of debugfs dir and file is failed, creating hsr interface
    will be failed. But debugfs doesn't affect actual logic of hsr module.
    So, ignoring this is more correct and this behavior is more general.

    Fixes: c5a759117210 ("net/hsr: Use list_head (and rcu) instead of array for slave devices.")
    Signed-off-by: Taehee Yoo
    Signed-off-by: David S. Miller

    Taehee Yoo
     

06 Dec, 2019

1 commit

  • hsr_dev_xmit() calls hsr_port_get_hsr() to find master node and that would
    return NULL if master node is not existing in the list.
    But hsr_dev_xmit() doesn't check return pointer so a NULL dereference
    could occur.

    Test commands:
    ip netns add nst
    ip link add veth0 type veth peer name veth1
    ip link add veth2 type veth peer name veth3
    ip link set veth1 netns nst
    ip link set veth3 netns nst
    ip link set veth0 up
    ip link set veth2 up
    ip link add hsr0 type hsr slave1 veth0 slave2 veth2
    ip a a 192.168.100.1/24 dev hsr0
    ip link set hsr0 up
    ip netns exec nst ip link set veth1 up
    ip netns exec nst ip link set veth3 up
    ip netns exec nst ip link add hsr1 type hsr slave1 veth1 slave2 veth3
    ip netns exec nst ip a a 192.168.100.2/24 dev hsr1
    ip netns exec nst ip link set hsr1 up
    hping3 192.168.100.2 -2 --flood &
    modprobe -rv hsr

    Splat looks like:
    [ 217.351122][ T1635] kasan: CONFIG_KASAN_INLINE enabled
    [ 217.352969][ T1635] kasan: GPF could be caused by NULL-ptr deref or user memory access
    [ 217.354297][ T1635] general protection fault: 0000 [#1] SMP DEBUG_PAGEALLOC KASAN PTI
    [ 217.355507][ T1635] CPU: 1 PID: 1635 Comm: hping3 Not tainted 5.4.0+ #192
    [ 217.356472][ T1635] Hardware name: innotek GmbH VirtualBox/VirtualBox, BIOS VirtualBox 12/01/2006
    [ 217.357804][ T1635] RIP: 0010:hsr_dev_xmit+0x34/0x90 [hsr]
    [ 217.373010][ T1635] Code: 48 8d be 00 0c 00 00 be 04 00 00 00 48 83 ec 08 e8 21 be ff ff 48 8d 78 10 48 ba 00 b
    [ 217.376919][ T1635] RSP: 0018:ffff8880cd8af058 EFLAGS: 00010202
    [ 217.377571][ T1635] RAX: 0000000000000000 RBX: ffff8880acde6840 RCX: 0000000000000002
    [ 217.379465][ T1635] RDX: dffffc0000000000 RSI: 0000000000000004 RDI: 0000000000000010
    [ 217.380274][ T1635] RBP: ffff8880acde6840 R08: ffffed101b440d5d R09: 0000000000000001
    [ 217.381078][ T1635] R10: 0000000000000001 R11: ffffed101b440d5c R12: ffff8880bffcc000
    [ 217.382023][ T1635] R13: ffff8880bffcc088 R14: 0000000000000000 R15: ffff8880ca675c00
    [ 217.383094][ T1635] FS: 00007f060d9d1740(0000) GS:ffff8880da000000(0000) knlGS:0000000000000000
    [ 217.384289][ T1635] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
    [ 217.385009][ T1635] CR2: 00007faf15381dd0 CR3: 00000000d523c001 CR4: 00000000000606e0
    [ 217.385940][ T1635] Call Trace:
    [ 217.386544][ T1635] dev_hard_start_xmit+0x160/0x740
    [ 217.387114][ T1635] __dev_queue_xmit+0x1961/0x2e10
    [ 217.388118][ T1635] ? check_object+0xaf/0x260
    [ 217.391466][ T1635] ? __alloc_skb+0xb9/0x500
    [ 217.392017][ T1635] ? init_object+0x6b/0x80
    [ 217.392629][ T1635] ? netdev_core_pick_tx+0x2e0/0x2e0
    [ 217.393175][ T1635] ? __alloc_skb+0xb9/0x500
    [ 217.393727][ T1635] ? rcu_read_lock_sched_held+0x90/0xc0
    [ 217.394331][ T1635] ? rcu_read_lock_bh_held+0xa0/0xa0
    [ 217.395013][ T1635] ? kasan_unpoison_shadow+0x30/0x40
    [ 217.395668][ T1635] ? __kasan_kmalloc.constprop.4+0xa0/0xd0
    [ 217.396280][ T1635] ? __kmalloc_node_track_caller+0x3a8/0x3f0
    [ 217.399007][ T1635] ? __kasan_kmalloc.constprop.4+0xa0/0xd0
    [ 217.400093][ T1635] ? __kmalloc_reserve.isra.46+0x2e/0xb0
    [ 217.401118][ T1635] ? memset+0x1f/0x40
    [ 217.402529][ T1635] ? __alloc_skb+0x317/0x500
    [ 217.404915][ T1635] ? arp_xmit+0xca/0x2c0
    [ ... ]

    Fixes: 311633b60406 ("hsr: switch ->dellink() to ->ndo_uninit()")
    Acked-by: Cong Wang
    Signed-off-by: Taehee Yoo
    Signed-off-by: David S. Miller

    Taehee Yoo
     

12 Jul, 2019

1 commit

  • Switching from ->priv_destructor to dellink() has an unexpected
    consequence: existing RCU readers, that is, hsr_port_get_hsr()
    callers, may still be able to read the port list.

    Instead of checking the return value of each hsr_port_get_hsr(),
    we can just move it to ->ndo_uninit() which is called after
    device unregister and synchronize_net(), and we still have RTNL
    lock there.

    Fixes: b9a1e627405d ("hsr: implement dellink to clean up resources")
    Fixes: edf070a0fb45 ("hsr: fix a NULL pointer deref in hsr_dev_xmit()")
    Reported-by: syzbot+097ef84cdc95843fbaa8@syzkaller.appspotmail.com
    Cc: Arvid Brodin
    Signed-off-by: Cong Wang
    Signed-off-by: David S. Miller

    Cong Wang
     

06 Jul, 2019

3 commits

  • hsr_port_get_hsr() could return NULL and kernel
    could crash:

    BUG: kernel NULL pointer dereference, address: 0000000000000010
    #PF: supervisor read access in kernel mode
    #PF: error_code(0x0000) - not-present page
    PGD 8000000074b84067 P4D 8000000074b84067 PUD 7057d067 PMD 0
    Oops: 0000 [#1] SMP PTI
    CPU: 0 PID: 754 Comm: a.out Not tainted 5.2.0-rc6+ #718
    Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.12.0-2.fc30 04/01/2014
    RIP: 0010:hsr_dev_xmit+0x20/0x31
    Code: 48 8b 1b eb e0 5b 5d 41 5c c3 66 66 66 66 90 55 48 89 fd 48 8d be 40 0b 00 00 be 04 00 00 00 e8 ee f2 ff ff 48 89 ef 48 89 c6 8b 40 10 48 89 45 10 e8 6c 1b 00 00 31 c0 5d c3 66 66 66 66 90
    RSP: 0018:ffffb5b400003c48 EFLAGS: 00010246
    RAX: 0000000000000000 RBX: ffff9821b4509a88 RCX: 0000000000000000
    RDX: ffff9821b4509a88 RSI: 0000000000000000 RDI: ffff9821bc3fc7c0
    RBP: ffff9821bc3fc7c0 R08: 0000000000000000 R09: 00000000000c2019
    R10: 0000000000000000 R11: 0000000000000002 R12: ffff9821bc3fc7c0
    R13: ffff9821b4509a88 R14: 0000000000000000 R15: 000000000000006e
    FS: 00007fee112a1800(0000) GS:ffff9821bd800000(0000) knlGS:0000000000000000
    CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
    CR2: 0000000000000010 CR3: 000000006e9ce000 CR4: 00000000000406f0
    Call Trace:

    netdev_start_xmit+0x1b/0x38
    dev_hard_start_xmit+0x121/0x21e
    ? validate_xmit_skb.isra.0+0x19/0x1e3
    __dev_queue_xmit+0x74c/0x823
    ? lockdep_hardirqs_on+0x12b/0x17d
    ip6_finish_output2+0x3d3/0x42c
    ? ip6_mtu+0x55/0x5c
    ? mld_sendpack+0x191/0x229
    mld_sendpack+0x191/0x229
    mld_ifc_timer_expire+0x1f7/0x230
    ? mld_dad_timer_expire+0x58/0x58
    call_timer_fn+0x12e/0x273
    __run_timers.part.0+0x174/0x1b5
    ? mld_dad_timer_expire+0x58/0x58
    ? sched_clock_cpu+0x10/0xad
    ? mark_lock+0x26/0x1f2
    ? __lock_is_held+0x40/0x71
    run_timer_softirq+0x26/0x48
    __do_softirq+0x1af/0x392
    irq_exit+0x53/0xa2
    smp_apic_timer_interrupt+0x1c4/0x1d9
    apic_timer_interrupt+0xf/0x20

    Cc: Arvid Brodin
    Signed-off-by: Cong Wang
    Signed-off-by: David S. Miller

    Cong Wang
     
  • hsr_link_ops implements ->newlink() but not ->dellink(),
    which leads that resources not released after removing the device,
    particularly the entries in self_node_db and node_db.

    So add ->dellink() implementation to replace the priv_destructor.
    This also makes the code slightly easier to understand.

    Reported-by: syzbot+c6167ec3de7def23d1e8@syzkaller.appspotmail.com
    Cc: Arvid Brodin
    Signed-off-by: Cong Wang
    Signed-off-by: David S. Miller

    Cong Wang
     
  • hsr_del_port() should release all the resources allocated
    in hsr_add_port().

    As a consequence of this change, hsr_for_each_port() is no
    longer safe to work with hsr_del_port(), switch to
    list_for_each_entry_safe() as we always hold RTNL lock.

    Cc: Arvid Brodin
    Signed-off-by: Cong Wang
    Signed-off-by: David S. Miller

    Cong Wang
     

16 Apr, 2019

2 commits


07 Apr, 2019

8 commits


08 Mar, 2019

1 commit

  • syzbot found another add_timer() issue, this time in net/hsr [1]

    Let's use mod_timer() which is safe.

    [1]
    kernel BUG at kernel/time/timer.c:1136!
    invalid opcode: 0000 [#1] PREEMPT SMP KASAN
    CPU: 0 PID: 15909 Comm: syz-executor.3 Not tainted 5.0.0+ #97
    Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011
    kobject: 'loop2' (00000000f5629718): kobject_uevent_env
    RIP: 0010:add_timer kernel/time/timer.c:1136 [inline]
    RIP: 0010:add_timer+0x654/0xbe0 kernel/time/timer.c:1134
    Code: 0f 94 c5 31 ff 44 89 ee e8 09 61 0f 00 45 84 ed 0f 84 77 fd ff ff e8 bb 5f 0f 00 e8 07 10 a0 ff e9 68 fd ff ff e8 ac 5f 0f 00 0b e8 a5 5f 0f 00 0f 0b e8 9e 5f 0f 00 4c 89 b5 58 ff ff ff e9
    RSP: 0018:ffff8880656eeca0 EFLAGS: 00010246
    kobject: 'loop2' (00000000f5629718): fill_kobj_path: path = '/devices/virtual/block/loop2'
    RAX: 0000000000040000 RBX: 1ffff1100caddd9a RCX: ffffc9000c436000
    RDX: 0000000000040000 RSI: ffffffff816056c4 RDI: ffff88806a2f6cc8
    RBP: ffff8880656eed58 R08: ffff888067f4a300 R09: ffff888067f4abc8
    R10: 0000000000000000 R11: 0000000000000000 R12: ffff88806a2f6cc0
    R13: dffffc0000000000 R14: 0000000000000001 R15: ffff8880656eed30
    FS: 00007fc2019bf700(0000) GS:ffff8880ae800000(0000) knlGS:0000000000000000
    CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
    CR2: 0000000000738000 CR3: 0000000067e8e000 CR4: 00000000001406f0
    DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
    DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
    Call Trace:
    hsr_check_announce net/hsr/hsr_device.c:99 [inline]
    hsr_check_carrier_and_operstate+0x567/0x6f0 net/hsr/hsr_device.c:120
    hsr_netdev_notify+0x297/0xa00 net/hsr/hsr_main.c:51
    notifier_call_chain+0xc7/0x240 kernel/notifier.c:93
    __raw_notifier_call_chain kernel/notifier.c:394 [inline]
    raw_notifier_call_chain+0x2e/0x40 kernel/notifier.c:401
    call_netdevice_notifiers_info+0x3f/0x90 net/core/dev.c:1739
    call_netdevice_notifiers_extack net/core/dev.c:1751 [inline]
    call_netdevice_notifiers net/core/dev.c:1765 [inline]
    dev_open net/core/dev.c:1436 [inline]
    dev_open+0x143/0x160 net/core/dev.c:1424
    team_port_add drivers/net/team/team.c:1203 [inline]
    team_add_slave+0xa07/0x15d0 drivers/net/team/team.c:1933
    do_set_master net/core/rtnetlink.c:2358 [inline]
    do_set_master+0x1d4/0x230 net/core/rtnetlink.c:2332
    do_setlink+0x966/0x3510 net/core/rtnetlink.c:2493
    rtnl_setlink+0x271/0x3b0 net/core/rtnetlink.c:2747
    rtnetlink_rcv_msg+0x465/0xb00 net/core/rtnetlink.c:5192
    netlink_rcv_skb+0x17a/0x460 net/netlink/af_netlink.c:2485
    rtnetlink_rcv+0x1d/0x30 net/core/rtnetlink.c:5210
    netlink_unicast_kernel net/netlink/af_netlink.c:1310 [inline]
    netlink_unicast+0x536/0x720 net/netlink/af_netlink.c:1336
    netlink_sendmsg+0x8ae/0xd70 net/netlink/af_netlink.c:1925
    sock_sendmsg_nosec net/socket.c:622 [inline]
    sock_sendmsg+0xdd/0x130 net/socket.c:632
    sock_write_iter+0x27c/0x3e0 net/socket.c:923
    call_write_iter include/linux/fs.h:1869 [inline]
    do_iter_readv_writev+0x5e0/0x8e0 fs/read_write.c:680
    do_iter_write fs/read_write.c:956 [inline]
    do_iter_write+0x184/0x610 fs/read_write.c:937
    vfs_writev+0x1b3/0x2f0 fs/read_write.c:1001
    do_writev+0xf6/0x290 fs/read_write.c:1036
    __do_sys_writev fs/read_write.c:1109 [inline]
    __se_sys_writev fs/read_write.c:1106 [inline]
    __x64_sys_writev+0x75/0xb0 fs/read_write.c:1106
    do_syscall_64+0x103/0x610 arch/x86/entry/common.c:290
    entry_SYSCALL_64_after_hwframe+0x49/0xbe
    RIP: 0033:0x457f29
    Code: ad b8 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 3d 01 f0 ff ff 0f 83 7b b8 fb ff c3 66 2e 0f 1f 84 00 00 00 00
    RSP: 002b:00007fc2019bec78 EFLAGS: 00000246 ORIG_RAX: 0000000000000014
    RAX: ffffffffffffffda RBX: 0000000000000003 RCX: 0000000000457f29
    RDX: 0000000000000001 RSI: 00000000200000c0 RDI: 0000000000000003
    RBP: 000000000073bf00 R08: 0000000000000000 R09: 0000000000000000
    R10: 0000000000000000 R11: 0000000000000246 R12: 00007fc2019bf6d4
    R13: 00000000004c4a60 R14: 00000000004dd218 R15: 00000000ffffffff

    Fixes: f421436a591d ("net/hsr: Add support for the High-availability Seamless Redundancy protocol (HSRv0)")
    Signed-off-by: Eric Dumazet
    Reported-by: syzbot
    Cc: Arvid Brodin
    Signed-off-by: David S. Miller

    Eric Dumazet
     

07 Mar, 2019

1 commit

  • If hsr_add_port(hsr, hsr_dev, HSR_PT_MASTER) failed to
    add port, it directly returns res and forgets to free the node
    that allocated in hsr_create_self_node(), and forgets to delete
    the node->mac_list linked in hsr->self_node_db.

    BUG: memory leak
    unreferenced object 0xffff8881cfa0c780 (size 64):
    comm "syz-executor.0", pid 2077, jiffies 4294717969 (age 2415.377s)
    hex dump (first 32 bytes):
    e0 c7 a0 cf 81 88 ff ff 00 02 00 00 00 00 ad de ................
    00 e6 49 cd 81 88 ff ff c0 9b 87 d0 81 88 ff ff ..I.............
    backtrace:
    [] hsr_dev_finalize+0x736/0x960 [hsr]
    [] hsr_newlink+0x2b2/0x3e0 [hsr]
    [] __rtnl_newlink+0xf1f/0x1600 net/core/rtnetlink.c:3182
    [] rtnl_newlink+0x66/0x90 net/core/rtnetlink.c:3240
    [] rtnetlink_rcv_msg+0x54e/0xb90 net/core/rtnetlink.c:5130
    [] netlink_rcv_skb+0x129/0x340 net/netlink/af_netlink.c:2477
    [] netlink_unicast_kernel net/netlink/af_netlink.c:1310 [inline]
    [] netlink_unicast+0x49a/0x650 net/netlink/af_netlink.c:1336
    [] netlink_sendmsg+0x88b/0xdf0 net/netlink/af_netlink.c:1917
    [] sock_sendmsg_nosec net/socket.c:621 [inline]
    [] sock_sendmsg+0xc3/0x100 net/socket.c:631
    [] __sys_sendto+0x33e/0x560 net/socket.c:1786
    [] __do_sys_sendto net/socket.c:1798 [inline]
    [] __se_sys_sendto net/socket.c:1794 [inline]
    [] __x64_sys_sendto+0xdd/0x1b0 net/socket.c:1794
    [] do_syscall_64+0x147/0x600 arch/x86/entry/common.c:290
    [] entry_SYSCALL_64_after_hwframe+0x49/0xbe
    [] 0xffffffffffffffff

    Fixes: c5a759117210 ("net/hsr: Use list_head (and rcu) instead of array for slave devices.")
    Reported-by: Hulk Robot
    Signed-off-by: Mao Wenan
    Signed-off-by: David S. Miller

    Mao Wenan
     

25 Oct, 2017

1 commit

  • In preparation for unconditionally passing the struct timer_list pointer to
    all timer callbacks, switch to using the new timer_setup() and from_timer()
    to pass the timer pointer explicitly.

    Cc: Arvid Brodin
    Cc: "David S. Miller"
    Cc: netdev@vger.kernel.org
    Signed-off-by: Kees Cook
    Signed-off-by: David S. Miller

    Kees Cook
     

23 Aug, 2017

1 commit

  • skb_put_padto() will free the sk_buff passed as reference in case of
    errors, but we still need to check its return value and decide what to
    do.

    Detected by CoverityScan, CID#1416688 ("CHECKED_RETURN")

    Fixes: ee1c27977284 ("net/hsr: Added support for HSR v1")
    Signed-off-by: Florian Fainelli
    Signed-off-by: David S. Miller

    Florian Fainelli
     

21 Jun, 2017

1 commit


08 Jun, 2017

1 commit

  • Network devices can allocate reasources and private memory using
    netdev_ops->ndo_init(). However, the release of these resources
    can occur in one of two different places.

    Either netdev_ops->ndo_uninit() or netdev->destructor().

    The decision of which operation frees the resources depends upon
    whether it is necessary for all netdev refs to be released before it
    is safe to perform the freeing.

    netdev_ops->ndo_uninit() presumably can occur right after the
    NETDEV_UNREGISTER notifier completes and the unicast and multicast
    address lists are flushed.

    netdev->destructor(), on the other hand, does not run until the
    netdev references all go away.

    Further complicating the situation is that netdev->destructor()
    almost universally does also a free_netdev().

    This creates a problem for the logic in register_netdevice().
    Because all callers of register_netdevice() manage the freeing
    of the netdev, and invoke free_netdev(dev) if register_netdevice()
    fails.

    If netdev_ops->ndo_init() succeeds, but something else fails inside
    of register_netdevice(), it does call ndo_ops->ndo_uninit(). But
    it is not able to invoke netdev->destructor().

    This is because netdev->destructor() will do a free_netdev() and
    then the caller of register_netdevice() will do the same.

    However, this means that the resources that would normally be released
    by netdev->destructor() will not be.

    Over the years drivers have added local hacks to deal with this, by
    invoking their destructor parts by hand when register_netdevice()
    fails.

    Many drivers do not try to deal with this, and instead we have leaks.

    Let's close this hole by formalizing the distinction between what
    private things need to be freed up by netdev->destructor() and whether
    the driver needs unregister_netdevice() to perform the free_netdev().

    netdev->priv_destructor() performs all actions to free up the private
    resources that used to be freed by netdev->destructor(), except for
    free_netdev().

    netdev->needs_free_netdev is a boolean that indicates whether
    free_netdev() should be done at the end of unregister_netdevice().

    Now, register_netdevice() can sanely release all resources after
    ndo_ops->ndo_init() succeeds, by invoking both ndo_ops->ndo_uninit()
    and netdev->priv_destructor().

    And at the end of unregister_netdevice(), we invoke
    netdev->priv_destructor() and optionally call free_netdev().

    Signed-off-by: David S. Miller

    David S. Miller
     

22 Feb, 2017

1 commit


21 Oct, 2016

1 commit

  • firewire-net:
    - set min/max_mtu
    - remove fwnet_change_mtu

    nes:
    - set max_mtu
    - clean up nes_netdev_change_mtu

    xpnet:
    - set min/max_mtu
    - remove xpnet_dev_change_mtu

    hippi:
    - set min/max_mtu
    - remove hippi_change_mtu

    batman-adv:
    - set max_mtu
    - remove batadv_interface_change_mtu
    - initialization is a little async, not 100% certain that max_mtu is set
    in the optimal place, don't have hardware to test with

    rionet:
    - set min/max_mtu
    - remove rionet_change_mtu

    slip:
    - set min/max_mtu
    - streamline sl_change_mtu

    um/net_kern:
    - remove pointless ndo_change_mtu

    hsi/clients/ssi_protocol:
    - use core MTU range checking
    - remove now redundant ssip_pn_set_mtu

    ipoib:
    - set a default max MTU value
    - Note: ipoib's actual max MTU can vary, depending on if the device is in
    connected mode or not, so we'll just set the max_mtu value to the max
    possible, and let the ndo_change_mtu function continue to validate any new
    MTU change requests with checks for CM or not. Note that ipoib has no
    min_mtu set, and thus, the network core's mtu > 0 check is the only lower
    bounds here.

    mptlan:
    - use net core MTU range checking
    - remove now redundant mpt_lan_change_mtu

    fddi:
    - min_mtu = 21, max_mtu = 4470
    - remove now redundant fddi_change_mtu (including export)

    fjes:
    - min_mtu = 8192, max_mtu = 65536
    - The max_mtu value is actually one over IP_MAX_MTU here, but the idea is to
    get past the core net MTU range checks so fjes_change_mtu can validate a
    new MTU against what it supports (see fjes_support_mtu in fjes_hw.c)

    hsr:
    - min_mtu = 0 (calls ether_setup, max_mtu is 1500)

    f_phonet:
    - min_mtu = 6, max_mtu = 65541

    u_ether:
    - min_mtu = 14, max_mtu = 15412

    phonet/pep-gprs:
    - min_mtu = 576, max_mtu = 65530
    - remove redundant gprs_set_mtu

    CC: netdev@vger.kernel.org
    CC: linux-rdma@vger.kernel.org
    CC: Stefan Richter
    CC: Faisal Latif
    CC: linux-rdma@vger.kernel.org
    CC: Cliff Whickman
    CC: Robin Holt
    CC: Jes Sorensen
    CC: Marek Lindner
    CC: Simon Wunderlich
    CC: Antonio Quartulli
    CC: Sathya Prakash
    CC: Chaitra P B
    CC: Suganath Prabu Subramani
    CC: MPT-FusionLinux.pdl@broadcom.com
    CC: Sebastian Reichel
    CC: Felipe Balbi
    CC: Arvid Brodin
    CC: Remi Denis-Courmont
    Signed-off-by: Jarod Wilson
    Signed-off-by: David S. Miller

    Jarod Wilson