VYPR
Moderate severityNVD Advisory· Published Apr 21, 2025· Updated Apr 21, 2025

Cilium packets from terminating endpoints may not be encrypted in Wireguard-enabled clusters

CVE-2025-32793

Description

Cilium is a networking, observability, and security solution with an eBPF-based dataplane. Versions 1.15.0 to 1.15.15, 1.16.0 to 1.16.8, and 1.17.0 to 1.17.2, are vulnerable when using Wireguard transparent encryption in a Cilium cluster, packets that originate from a terminating endpoint can leave the source node without encryption due to a race condition in how traffic is processed by Cilium. This issue has been patched in versions 1.15.16, 1.16.9, and 1.17.3. There are no workarounds available for this issue.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
github.com/cilium/ciliumGo
>= 1.13.0, < 1.15.161.15.16
github.com/cilium/ciliumGo
>= 1.16.0, < 1.16.91.16.9
github.com/cilium/ciliumGo
>= 1.17.0, < 1.17.31.17.3

Affected products

1

Patches

1
e8543eef0512

bpf: wireguard: avoid ipcache lookup for source's security identity

https://github.com/cilium/ciliumJulian WiedmannMar 28, 2025via ghsa
2 files changed · +25 10
  • bpf/bpf_host.c+3 2 modified
    @@ -57,7 +57,8 @@
     #include "lib/vtep.h"
     
      #define host_egress_policy_hook(ctx, src_sec_identity, ext_err) CTX_ACT_OK
    - #define host_wg_encrypt_hook(ctx, proto) wg_maybe_redirect_to_encrypt(ctx, proto)
    + #define host_wg_encrypt_hook(ctx, proto, src_sec_identity)			\
    +	 wg_maybe_redirect_to_encrypt(ctx, proto, src_sec_identity)
     
     /* Bit 0 is skipped for robustness, as it's used in some places to indicate from_host itself. */
     #define FROM_HOST_FLAG_NEED_HOSTFW (1 << 1)
    @@ -1625,7 +1626,7 @@ int cil_to_netdev(struct __ctx_buff *ctx)
     	 * is set before the redirect.
     	 */
     	if (!ctx_mark_is_wireguard(ctx)) {
    -		ret = host_wg_encrypt_hook(ctx, proto);
    +		ret = host_wg_encrypt_hook(ctx, proto, src_sec_identity);
     		if (ret == CTX_ACT_REDIRECT)
     			return ret;
     		else if (IS_ERR(ret))
    
  • bpf/lib/wireguard.h+22 8 modified
    @@ -57,7 +57,8 @@ ctx_is_wireguard(struct __ctx_buff *ctx, int l4_off, __u8 protocol, __u32 identi
     }
     
     static __always_inline int
    -wg_maybe_redirect_to_encrypt(struct __ctx_buff *ctx, __be16 proto)
    +wg_maybe_redirect_to_encrypt(struct __ctx_buff *ctx, __be16 proto,
    +			     __u32 src_sec_identity)
     {
     	struct remote_endpoint_info *dst = NULL;
     	struct remote_endpoint_info __maybe_unused *src = NULL;
    @@ -96,7 +97,14 @@ wg_maybe_redirect_to_encrypt(struct __ctx_buff *ctx, __be16 proto)
     		}
     #endif
     		dst = lookup_ip6_remote_endpoint((union v6addr *)&ip6->daddr, 0);
    -		src = lookup_ip6_remote_endpoint((union v6addr *)&ip6->saddr, 0);
    +
    +		if (src_sec_identity == UNKNOWN_ID) {
    +			src = lookup_ip6_remote_endpoint((union v6addr *)&ip6->saddr, 0);
    +			if (!src)
    +				return CTX_ACT_OK;
    +
    +			src_sec_identity = src->sec_identity;
    +		}
     		break;
     #endif
     #ifdef ENABLE_IPV4
    @@ -115,7 +123,14 @@ wg_maybe_redirect_to_encrypt(struct __ctx_buff *ctx, __be16 proto)
     # endif /* HAVE_ENCAP */
     
     		dst = lookup_ip4_remote_endpoint(ip4->daddr, 0);
    -		src = lookup_ip4_remote_endpoint(ip4->saddr, 0);
    +
    +		if (src_sec_identity == UNKNOWN_ID) {
    +			src = lookup_ip4_remote_endpoint(ip4->saddr, 0);
    +			if (!src)
    +				return CTX_ACT_OK;
    +
    +			src_sec_identity = src->sec_identity;
    +		}
     		break;
     #endif
     	default:
    @@ -146,29 +161,28 @@ wg_maybe_redirect_to_encrypt(struct __ctx_buff *ctx, __be16 proto)
     	 * This means that the packet won't be encrypted. This is fine,
     	 * as with --encrypt-node=false we encrypt only pod-to-pod packets.
     	 */
    -	if (!src || src->sec_identity == HOST_ID)
    +	if (src_sec_identity == HOST_ID)
     		goto out;
     #endif /* !ENABLE_NODE_ENCRYPTION */
     
     	/* We don't want to encrypt any traffic that originates from outside
     	 * the cluster. This check excludes DSR traffic from the LB node to a remote backend.
     	 */
    -	if (!src || !identity_is_cluster(src->sec_identity))
    +	if (!identity_is_cluster(src_sec_identity))
     		goto out;
     
     	/* If source is remote node we should treat it like outside traffic.
     	 * This is possible when connection is done from pod to load balancer with DSR enabled.
     	 */
    -	if (identity_is_remote_node(src->sec_identity))
    +	if (identity_is_remote_node(src_sec_identity))
     		goto out;
     
     maybe_encrypt: __maybe_unused
     	/* Redirect to the WireGuard tunnel device if the encryption is
     	 * required.
     	 */
     	if (dst && dst->key) {
    -		if (src)
    -			set_identity_mark(ctx, src->sec_identity, MARK_MAGIC_IDENTITY);
    +		set_identity_mark(ctx, src_sec_identity, MARK_MAGIC_IDENTITY);
     overlay_encrypt: __maybe_unused
     		return ctx_redirect(ctx, WG_IFINDEX, 0);
     	}
    

Vulnerability mechanics

Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

5

News mentions

0

No linked articles in our index yet.