Open vSwitch (OVS) is a widely used virtual switch in Linux environments, especially for software-defined networking (SDN), virtualization, and cloud platforms. In 2021, a vulnerability was reported and subsequently resolved in the Linux kernel component supporting OVS, which could potentially allow an attacker to trigger a stack-based out-of-bounds (OOB) read when fragmenting IPv4 packets. This post explains the bug, how it can be triggered, and how it was fixed — in plain English.

The CVE Details

- CVE ID: CVE-2021-46955

Affected Software: Linux kernel (specifically Open vSwitch module)

- Vulnerable Kernel Versions: Before the fix in this commit, e.g. v5.12-rc6 and similar.
- Fixed in kernel: v5.12-rc7 and above

What’s the Issue?

When OVS needs to fragment IPv4 packets, it temporarily uses a struct dst_entry on the C stack. An IPv4-specific path in the kernel later treats this object as a struct rtable due to how routing and MTU (Maximum Transmission Unit) information is fetched. However, struct rtable is *bigger* than struct dst_entry and has more fields. That means reading past the end of the temporary stack buffer: stack out-of-bounds read.

This can happen when you, your container, or your VM triggers packet fragmentation using OVS.

Kernel AddressSanitizer (KASAN) Symptoms

If you run KASAN-enabled kernel, you might see stack OOB warnings such as:

BUG: KASAN: stack-out-of-bounds in ip_do_fragment+x1b03/x1f60
Read of size 1 at addr ffff888112fc713c by task handler2/1367

...with a call trace resembling

ip_do_fragment
  ip_skb_dst_mtu
    ip_dst_mtu_maybe_forward
      ip_mtu_locked

Why is this Dangerous?

Stack OOB reads leak adjacent stack memory. While this particular bug seems not to allow direct code execution (it's a read, not a write), it:

The Code Path

Here's an (annotated) version of the problematic snippet. For IPv4, a temporary struct dst_entry is put on the stack.

Vulnerable OVS Code Fragment

/*
 * Inside the OVS module (openvswitch/datapath.c)
 * Function: ovs_fragment()
 */
struct dst_entry ovs_dst;
...
/* Use ovs_dst as a temporary destination */
skb_dst_set(skb, &ovs_dst);
/* Later */
ip_do_fragment(skb);
/* Inside ip_do_fragment() and transitively ip_skb_dst_mtu()... */

But! The kernel expects a struct rtable

static inline unsigned int ip_dst_mtu_maybe_forward(const struct dst_entry *dst)
{
    const struct rtable *rt = (const struct rtable *) dst;
    if (ip_mtu_locked(rt))
        return dst_mtu(dst);
    ...
}

ip_mtu_locked() reads a field only present in a full struct rtable

static inline bool ip_mtu_locked(const struct rtable *rt)
{
    return rt->rt_mtu_locked;
}

This causes reading off the end of your local ovs_dst stack object, colliding with whatever is next on the stack (ovs_rt or other data).

The Stack Layout (from the bug)

this frame has 2 objects:
  32, 144) 'ovs_dst'
  [192, 424) 'ovs_rt'


So reading outside 'ovs_dst' can peek into 'ovs_rt', or, if the gap is too small, unknown memory.
PoC SketchThen watch dmesg for stack OOB warnings.

## The Patch / How It Was Fixed

The patch simply allocates a struct rtable on the stack when dealing with IPv4, instead of just a struct dst_entry. This way, accesses like rt->rt_mtu_locked are safe. The relevant upstream commit is [here
.

Fixed Code Snippet

#ifdef HAVE_IPV6
    struct rt6_info ovs_rt6;
#endif
#if IS_ENABLED(CONFIG_INET)
    struct rtable ovs_rt;
#endif
    struct dst_entry *ovs_dst;
/* ... */
#if IS_ENABLED(CONFIG_INET)
    if (skb->protocol == htons(ETH_P_IP)) {
        memset(&ovs_rt, , sizeof(ovs_rt));
        ovs_dst = &ovs_rt.dst;
    }
#endif

This makes sure the temporary on-stack object is large enough for all accesses.

- CVE-2021-46955 @ NVD
- Upstream patch commit
- KASAN docs
- Original mailing list report
- Open vSwitch Homepage

Impact & Recommendations

While exploitation as a privilege escalation is unlikely in most settings, stack OOB reads in kernel code can be a springboard for more dangerous attacks, especially when KASAN or similar tools are not in use. Always run up-to-date kernels, especially in VPS, container, or cloud environments using Open vSwitch or any heavy virtual networking.

Check your kernel: If you use OVS and your kernel is older than May 2021, verify you have the fix for CVE-2021-46955!


*This summary was crafted for clarity and practical understanding. For your own code and systems, always check upstream references.*

Timeline

Published on: 02/27/2024 19:04:06 UTC
Last modified on: 12/06/2024 17:53:52 UTC