// For flags

CVE-2021-47546

ipv6: fix memory leak in fib6_rule_suppress

Severity Score

5.5
*CVSS v3.1

Exploit Likelihood

*EPSS

Affected Versions

*CPE

Public Exploits

0
*Multiple Sources

Exploited in Wild

-
*KEV

Decision

Track
*SSVC
Descriptions

In the Linux kernel, the following vulnerability has been resolved:

ipv6: fix memory leak in fib6_rule_suppress

The kernel leaks memory when a `fib` rule is present in IPv6 nftables
firewall rules and a suppress_prefix rule is present in the IPv6 routing
rules (used by certain tools such as wg-quick). In such scenarios, every
incoming packet will leak an allocation in `ip6_dst_cache` slab cache.

After some hours of `bpftrace`-ing and source code reading, I tracked
down the issue to ca7a03c41753 ("ipv6: do not free rt if
FIB_LOOKUP_NOREF is set on suppress rule").

The problem with that change is that the generic `args->flags` always have
`FIB_LOOKUP_NOREF` set[1][2] but the IPv6-specific flag
`RT6_LOOKUP_F_DST_NOREF` might not be, leading to `fib6_rule_suppress` not
decreasing the refcount when needed.

How to reproduce:
- Add the following nftables rule to a prerouting chain:
meta nfproto ipv6 fib saddr . mark . iif oif missing drop
This can be done with:
sudo nft create table inet test
sudo nft create chain inet test test_chain '{ type filter hook prerouting priority filter + 10; policy accept; }'
sudo nft add rule inet test test_chain meta nfproto ipv6 fib saddr . mark . iif oif missing drop
- Run:
sudo ip -6 rule add table main suppress_prefixlength 0
- Watch `sudo slabtop -o | grep ip6_dst_cache` to see memory usage increase
with every incoming ipv6 packet.

This patch exposes the protocol-specific flags to the protocol
specific `suppress` function, and check the protocol-specific `flags`
argument for RT6_LOOKUP_F_DST_NOREF instead of the generic
FIB_LOOKUP_NOREF when decreasing the refcount, like this.

[1]: https://github.com/torvalds/linux/blob/ca7a03c4175366a92cee0ccc4fec0038c3266e26/net/ipv6/fib6_rules.c#L71
[2]: https://github.com/torvalds/linux/blob/ca7a03c4175366a92cee0ccc4fec0038c3266e26/net/ipv6/fib6_rules.c#L99

En el kernel de Linux, se resolvió la siguiente vulnerabilidad: ipv6: corrige la pérdida de memoria en fib6_rule_suppress El kernel pierde memoria cuando una regla `fib` está presente en las reglas de firewall de nftables de IPv6 y una regla de supresión_prefix está presente en las reglas de enrutamiento de IPv6 (utilizadas por ciertas herramientas como wg-quick). En tales escenarios, cada paquete entrante perderá una asignación en el caché de losa `ip6_dst_cache`. Después de algunas horas de `bpftrace`-ing y lectura del código fuente, rastreé el problema hasta ca7a03c41753 ("ipv6: no libere rt si FIB_LOOKUP_NOREF está configurado en la regla de supresión"). El problema con ese cambio es que los `args->flags` genéricos siempre tienen `FIB_LOOKUP_NOREF` configurado[1][2] pero el indicador específico de IPv6 `RT6_LOOKUP_F_DST_NOREF` podría no estarlo, lo que lleva a que `fib6_rule_suppress` no disminuya el recuento cuando necesario. Cómo reproducir: - Agregue la siguiente regla nftables a una cadena de enrutamiento previo: meta nfproto ipv6 fib saddr. marca . iif oif falta gota Esto se puede hacer con: sudo nft create table inet test sudo nft create chain inet test test_chain '{ tipo filtro gancho prerouting filtro de prioridad + 10; aceptar política; }' sudo nft agregar regla inet test test_chain meta nfproto ipv6 fib saddr. marca . iif oif falta gota - Ejecutar: sudo ip -6 regla agregar tabla principal suprimir_prefixlength 0 - Ver `sudo slabtop -o | grep ip6_dst_cache` para ver el aumento del uso de memoria con cada paquete ipv6 entrante. Este parche expone los indicadores específicos del protocolo a la función `suprimir` específica del protocolo y verifica el argumento `flags` específico del protocolo para RT6_LOOKUP_F_DST_NOREF en lugar del FIB_LOOKUP_NOREF genérico al disminuir el recuento, de esta manera. [1]: https://github.com/torvalds/linux/blob/ca7a03c4175366a92cee0ccc4fec0038c3266e26/net/ipv6/fib6_rules.c#L71 [2]: https://github.com/torvalds/linux/blob/ca7a03c4175366a92cee0ccc4fec0038 c3266e26/net /ipv6/fib6_rules.c#L99

*Credits: N/A
CVSS Scores
Attack Vector
Local
Attack Complexity
Low
Privileges Required
Low
User Interaction
None
Scope
Unchanged
Confidentiality
None
Integrity
None
Availability
High
* Common Vulnerability Scoring System
SSVC
  • Decision:Track
Exploitation
None
Automatable
No
Tech. Impact
Partial
* Organization's Worst-case Scenario
Timeline
  • 2024-05-24 CVE Reserved
  • 2024-05-24 CVE Published
  • 2024-06-11 EPSS Updated
  • 2024-08-04 CVE Updated
  • ---------- Exploited in Wild
  • ---------- KEV Due Date
  • ---------- First Exploit
CWE
  • CWE-401: Missing Release of Memory after Effective Lifetime
CAPEC
Affected Vendors, Products, and Versions
Vendor Product Version Other Status
Vendor Product Version Other Status <-- --> Vendor Product Version Other Status
Linux
Search vendor "Linux"
Linux Kernel
Search vendor "Linux" for product "Linux Kernel"
>= 5.4 < 5.4.164
Search vendor "Linux" for product "Linux Kernel" and version " >= 5.4 < 5.4.164"
en
Affected
Linux
Search vendor "Linux"
Linux Kernel
Search vendor "Linux" for product "Linux Kernel"
>= 5.4 < 5.10.84
Search vendor "Linux" for product "Linux Kernel" and version " >= 5.4 < 5.10.84"
en
Affected
Linux
Search vendor "Linux"
Linux Kernel
Search vendor "Linux" for product "Linux Kernel"
>= 5.4 < 5.15.7
Search vendor "Linux" for product "Linux Kernel" and version " >= 5.4 < 5.15.7"
en
Affected
Linux
Search vendor "Linux"
Linux Kernel
Search vendor "Linux" for product "Linux Kernel"
>= 5.4 < 5.16
Search vendor "Linux" for product "Linux Kernel" and version " >= 5.4 < 5.16"
en
Affected
Linux
Search vendor "Linux"
Linux Kernel
Search vendor "Linux" for product "Linux Kernel"
5.2.19
Search vendor "Linux" for product "Linux Kernel" and version "5.2.19"
en
Affected
Linux
Search vendor "Linux"
Linux Kernel
Search vendor "Linux" for product "Linux Kernel"
5.3.4
Search vendor "Linux" for product "Linux Kernel" and version "5.3.4"
en
Affected