[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[BUG] Potential double-free in Xen dt-overlay attach/remove error path


  • To: xen-devel@xxxxxxxxxxxxxxxxxxxx
  • From: Gyujeong Jin <wlsrbwjd7232@xxxxxxxxx>
  • Date: Fri, 10 Apr 2026 06:28:43 +0900
  • Arc-authentication-results: i=1; mx.google.com; arc=none
  • Arc-message-signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20240605; h=to:subject:message-id:date:from:mime-version:dkim-signature; bh=aZcPhsgjXmF9WMlgqBsdubbSdhhYn+eTZxnIn/m7ywU=; fh=quJY5mN2l4ZorNvEoO9ngNXalhEvTdq/+W8CvHWhECs=; b=k827168fVzPf42PbtRVksLB84tUEtZ2BcnYGwH+SgAGrf7awj6WdCMV6rT/7dTnSxb 8kf1QtJsgv0jig0HCvcLFfZYj+0tfJs3P3f/z4H9XfGTcEi2OFwK1nhG15XAoP+nb3z8 83GGHWv3iHMVGASku8ufJu44DSc3j6WxUcJ30HsK4MVmVPPr7Y/Tg18KhQdsQQ31kPme tX0sCoBWFHUQhLxxOJ0qwhoUX7rlZI4uhJjIeIQZprn9d2+KsHhHyZfoe/QNJZqcXwXj R0nMg8g0CI9t+6l/7JzINY2EYsQpmgFQrH2HQ/qhPDB4Hoy5oopdKVVb9na0Cbk4xY4r ccWQ==; darn=lists.xenproject.org
  • Arc-seal: i=1; a=rsa-sha256; t=1775770136; cv=none; d=google.com; s=arc-20240605; b=a5zr7ryotsWX88rl8m0BMIK6PO8fNpS/VxY5SVD4JDBBSNCv3lMmooyMYI+qjyUb/7 v/EYruYoXKkqutYReHVrgmEXAxRdbG6UtGEc3I4I/2CTDflpofS6Tw0V43pjJ/7SjUrZ MXGnCWwS6cB7faG/8eg/86QhpzG/KQhdt5pGOihLG7wu7Wk2U6aagXu9K36itGE7XZJ7 FNx35Wlb2x5UIMPeJwR6V8deI1ziEAKpB/NLbtwpXR/k5e2i/Iqk3sV9oOL87D9sURrS joDprxMXqR4DWjvI9o9DdvMETcalxI65hgGtg2c+qeAhPJbhK7O0jXFNRdAMEgEchEpR mucA==
  • Authentication-results: eu.smtp.expurgate.cloud; dkim=pass header.s=20251104 header.d=gmail.com header.i="@gmail.com" header.h="To:Subject:Message-ID:Date:From:MIME-Version"
  • Delivery-date: Thu, 09 Apr 2026 21:40:24 +0000
  • List-id: Xen developer discussion <xen-devel.lists.xenproject.org>

Hello Team, I was advised to report this issue in this way because dt-overlay is currently experimental and not security supported.

I would like to report a potential memory safety issue in Xen related to the Device Tree overlay handling logic.


Problem Description

A double-free / use-after-free condition may occur in the dt-overlay handling path when an overlay attachment fails and the same overlay is later removed.

The issue arises because rangeset objects are freed on the failure path of handle_attach_overlay_nodes(), but the corresponding pointers are not cleared. Subsequently, handle_remove_overlay_nodes() may operate on these stale pointers, leading to a second free.

Affected Component

  • Xen ARM
  • Device Tree overlay subsystem
  • File: xen/common/device-tree/dt-overlay.c

Relevant functions:

  • handle_attach_overlay_nodes()
  • handle_remove_overlay_nodes()

Impact

This issue may lead to:

  • Double-free of rangeset structures
  • Use-after-free when accessing stale pointers
  • Potential hypervisor crash (DoS)
  • Possible memory corruption depending on allocator behavior

Given that this occurs in the hypervisor context, the impact could extend beyond a simple crash under certain conditions.

Root Cause

The issue originates from inconsistent memory management between the attach failure path and the remove path.

In handle_attach_overlay_nodes(), the failure path frees rangeset objects:

static long handle_attach_overlay_nodes(...)
{
    ...

    if ( entry )
    {
        rangeset_destroy(entry->irq_ranges);
        rangeset_destroy(entry->iomem_ranges);
    }

    return rc;
}

However, the corresponding pointers (entry->irq_ranges and entry->iomem_ranges) are not set to NULL afterward, leaving dangling pointers in the entry structure.

Later, in handle_remove_overlay_nodes(), the same fields are used again:

static long handle_remove_overlay_nodes(const void *overlay_fdt,
                                        uint32_t overlay_fdt_size)
{
    ...

    rc = remove_nodes(entry);

    ...

    rangeset_destroy(entry->irq_ranges);
    rangeset_destroy(entry->iomem_ranges);

    ...
}

static int remove_nodes(const struct overlay_track *tracker)
{
    /* Remove IRQ access. */
    if ( tracker->irq_ranges )
    {
        rc = rangeset_consume_ranges(tracker->irq_ranges, irq_remove_cb, d);
        if ( rc )
            return rc;
    }

   /* Remove mmio access. */
    if ( tracker->iomem_ranges )
    {
        rc = rangeset_consume_ranges(tracker->iomem_ranges, iomem_remove_cb, d);
        if ( rc )
            return rc;
    }

    return rc;
}

Since the pointers were not invalidated after being freed, this leads to:

  • reuse of freed memory in rangeset_consume_ranges()
  • double-free in rangeset_destroy()

This creates a double-free / use-after-free condition.

Environment

  • Xen: 4.22-dev-517-g500ee5fe0f
  • Platform: Linux (WSL2 environment)

Suggested Fix

After calling rangeset_destroy(), the corresponding pointers should be set to NULL to prevent reuse:

entry->irq_ranges = NULL;
entry->iomem_ranges = NULL;

Alternatively, the remove path should defensively check pointer validity.

Best regards, Gyujeong Jin (Giunash)


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.