• Niels Dossche's avatar
    ipv6: fix locking issues with loops over idev->addr_list · 51454ea4
    Niels Dossche authored
    idev->addr_list needs to be protected by idev->lock. However, it is not
    always possible to do so while iterating and performing actions on
    inet6_ifaddr instances. For example, multiple functions (like
    addrconf_{join,leave}_anycast) eventually call down to other functions
    that acquire the idev->lock. The current code temporarily unlocked the
    idev->lock during the loops, which can cause race conditions. Moving the
    locks up is also not an appropriate solution as the ordering of lock
    acquisition will be inconsistent with for example mc_lock.
    
    This solution adds an additional field to inet6_ifaddr that is used
    to temporarily add the instances to a temporary list while holding
    idev->lock. The temporary list can then be traversed without holding
    idev->lock. This change was done in two places. In addrconf_ifdown, the
    list_for_each_entry_safe variant of the list loop is also no longer
    necessary as there is no deletion within that specific loop.
    Suggested-by: default avatarPaolo Abeni <pabeni@redhat.com>
    Signed-off-by: default avatarNiels Dossche <dossche.niels@gmail.com>
    Acked-by: default avatarPaolo Abeni <pabeni@redhat.com>
    Link: https://lore.kernel.org/r/20220403231523.45843-1-dossche.niels@gmail.comSigned-off-by: default avatarJakub Kicinski <kuba@kernel.org>
    51454ea4
addrconf.c 179 KB