CVE-2024-56644

Severity CVSS v4.0:
Pending analysis
Type:
Unavailable / Other
Publication date:
27/12/2024
Last modified:
27/12/2024

Description

In the Linux kernel, the following vulnerability has been resolved:<br /> <br /> net/ipv6: release expired exception dst cached in socket<br /> <br /> Dst objects get leaked in ip6_negative_advice() when this function is<br /> executed for an expired IPv6 route located in the exception table. There<br /> are several conditions that must be fulfilled for the leak to occur:<br /> * an ICMPv6 packet indicating a change of the MTU for the path is received,<br /> resulting in an exception dst being created<br /> * a TCP connection that uses the exception dst for routing packets must<br /> start timing out so that TCP begins retransmissions<br /> * after the exception dst expires, the FIB6 garbage collector must not run<br /> before TCP executes ip6_negative_advice() for the expired exception dst<br /> <br /> When TCP executes ip6_negative_advice() for an exception dst that has<br /> expired and if no other socket holds a reference to the exception dst, the<br /> refcount of the exception dst is 2, which corresponds to the increment<br /> made by dst_init() and the increment made by the TCP socket for which the<br /> connection is timing out. The refcount made by the socket is never<br /> released. The refcount of the dst is decremented in sk_dst_reset() but<br /> that decrement is counteracted by a dst_hold() intentionally placed just<br /> before the sk_dst_reset() in ip6_negative_advice(). After<br /> ip6_negative_advice() has finished, there is no other object tied to the<br /> dst. The socket lost its reference stored in sk_dst_cache and the dst is<br /> no longer in the exception table. The exception dst becomes a leaked<br /> object.<br /> <br /> As a result of this dst leak, an unbalanced refcount is reported for the<br /> loopback device of a net namespace being destroyed under kernels that do<br /> not contain e5f80fcf869a ("ipv6: give an IPv6 dev to blackhole_netdev"):<br /> unregister_netdevice: waiting for lo to become free. Usage count = 2<br /> <br /> Fix the dst leak by removing the dst_hold() in ip6_negative_advice(). The<br /> patch that introduced the dst_hold() in ip6_negative_advice() was<br /> 92f1655aa2b22 ("net: fix __dst_negative_advice() race"). But 92f1655aa2b22<br /> merely refactored the code with regards to the dst refcount so the issue<br /> was present even before 92f1655aa2b22. The bug was introduced in<br /> 54c1a859efd9f ("ipv6: Don&amp;#39;t drop cache route entry unless timer actually<br /> expired.") where the expired cached route is deleted and the sk_dst_cache<br /> member of the socket is set to NULL by calling dst_negative_advice() but<br /> the refcount belonging to the socket is left unbalanced.<br /> <br /> The IPv4 version - ipv4_negative_advice() - is not affected by this bug.<br /> When the TCP connection times out ipv4_negative_advice() merely resets the<br /> sk_dst_cache of the socket while decrementing the refcount of the<br /> exception dst.

Impact