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

Re: [PATCH v2] arm/mm: Fix resource handling in xenmem_add_to_physmap_one


  • To: Jan Beulich <jbeulich@xxxxxxxx>
  • From: "Orzel, Michal" <michal.orzel@xxxxxxx>
  • Date: Thu, 19 Mar 2026 19:05:52 +0100
  • Arc-authentication-results: i=1; mx.microsoft.com 1; spf=pass (sender ip is 165.204.84.17) smtp.rcpttodomain=suse.com smtp.mailfrom=amd.com; dmarc=pass (p=quarantine sp=quarantine pct=100) action=none header.from=amd.com; dkim=none (message not signed); arc=none (0)
  • Arc-message-signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=OZANLZEI6DRiruIrvsX+EAhBp9NWBIl/2ewp6ajlTNs=; b=w36NgjtCOXzrn/zhwsox1HV6dVwzW6cvbUtTFXsZklDpPGuiVsBSodtFrYcxa6s7/UV3mfoITFV6JtO/yQLcbTq3UGFyLU9pSjhW6TUDjoJ8Mm8elY0hJynEYDC1g52+iMretZkc1E8VB96Yq2dDw+qf7kAM+7DNMMbRKUkuYYMOwzsE6d77rfo3qRs+0EYCe1XbxoscCql5SLkpL9idwuKCOcQ0cDwF31N6lBZZbh9M8uP7RglldOf9QsuDuzcn1dmwvWb0vZBSDiVAvNMt6fzFE1KFT0CUlegTyPVD0PLYANDH/6JSMzboaWSUAkONVKMw5XZoTfYOpy/6UqNijw==
  • Arc-seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=AFfZjtN7Fjm1Xr6tzFSfFiYiU9DOoLS+MOwIuITqwC5XlgZCeNm1SKExjNFoVxo9do3wd2EQdMzUkRXWkv8/ekeYb9cLtcET4fgqrStKVXONQHPPvAOlLtlhrgnUAjhUrzG2+6RaaUg8D1Fkv9RQf29uH6AENZzALBmwknrurj8P8gXg1Bnk9FMrgvtH2CIGrbtL/mZolVVLcJOwJj6kj7wQzr5BroLayij1ZsQsm1pqMYeK5zx5vHsI8DYmHGt2Oz91SLtDxVyWmeceNkM1SKz/gddeW6PEAHogsid6JPfTU5PszZSCm7VBbRBhmkIzjbxL2ik6kjDL8ScMfp0r2w==
  • Cc: Stefano Stabellini <sstabellini@xxxxxxxxxx>, Julien Grall <julien@xxxxxxx>, Bertrand Marquis <bertrand.marquis@xxxxxxx>, Volodymyr Babchuk <Volodymyr_Babchuk@xxxxxxxx>, <xen-devel@xxxxxxxxxxxxxxxxxxxx>
  • Delivery-date: Thu, 19 Mar 2026 18:06:26 +0000
  • List-id: Xen developer discussion <xen-devel.lists.xenproject.org>


On 04/03/2026 11:43, Jan Beulich wrote:
> On 04.03.2026 10:39, Michal Orzel wrote:
>> @@ -237,13 +239,73 @@ int xenmem_add_to_physmap_one(
>>          break;
>>      }
>>      case XENMAPSPACE_dev_mmio:
>> -        rc = map_dev_mmio_page(d, gfn, _mfn(idx));
>> -        return rc;
>> +        if ( !iomem_access_permitted(d, idx, idx) )
>> +            return 0;
>> +
>> +        mfn = _mfn(idx);
>> +        t = p2m_mmio_direct_c;
>> +        break;
>>  
>>      default:
>>          return -ENOSYS;
>>      }
>>  
>> +    /*
>> +     * Release the old page reference if it was present.
>> +     *
>> +     * TODO: There are race conditions in this code due to multiple 
>> lock/unlock
>> +     * cycles:
>> +     *
>> +     * Race #1: Between checking the old mapping and removing it, another 
>> CPU
>> +     * could replace the mapping. We would then remove the wrong mapping.
>> +     *
>> +     * Race #2: Between removing the old mapping and inserting the new one,
>> +     * another CPU could insert a different mapping. We would then silently
>> +     * overwrite it.
> 
> Can't such races be abused in a security relevant way, e.g. causing leaks of
> some sort?
AFAICT (I though of a few scenarios), the race can only reproduce the pre-patch
behavior - pages leaked until domain destruction. After this patch, it only
happens if two vCPUs race on the same GFN.

> 
>> +     * For now, we accept these races as they require concurrent
>> +     * xenmem_add_to_physmap_one operations on the same GFN, which is not a
>> +     * normal usage pattern.
>> +     */
>> +    p2m_read_lock(p2m);
>> +    mfn_old = p2m_get_entry(p2m, gfn, &p2mt_old, NULL, NULL, NULL);
>> +    p2m_read_unlock(p2m);
>> +
>> +    if ( mfn_valid(mfn_old) && !mfn_eq(mfn, mfn_old) )
>> +    {
>> +        if ( is_special_page(mfn_to_page(mfn_old)) )
>> +        {
>> +            /* Just unmap, don't free */
>> +            p2m_write_lock(p2m);
>> +            rc = p2m_set_entry(p2m, gfn, 1, INVALID_MFN,
>> +                               p2m_invalid, p2m->default_access);
>> +            p2m_write_unlock(p2m);
>> +            if ( rc )
>> +                goto out;
>> +        }
>> +        else if ( p2m_is_mmio(p2mt_old) || p2m_is_grant(p2mt_old) )
>> +        {
>> +            /* Reject MMIO and grant replacements */
>> +            rc = -EPERM;
>> +            goto out;
>> +        }
>> +        else
>> +        {
>> +            /* Allow RAM and foreign - both have proper cleanup */
>> +            rc = guest_remove_page(d, gfn_x(gfn));
>> +            if ( rc )
>> +                goto out;
>> +        }
>> +    }
>> +    else if ( mfn_valid(mfn_old) )
>> +    {
>> +        /* Mapping already exists. Drop the references taken above */
>> +        if ( page != NULL )
>> +            put_page(page);
>> +
>> +        return 0;
> 
> Is this correct regardless of p2mt_old?
> 
>> +    }
> 
> !mfn_valid(mfn_old) doesn't imply there was no valid mapping. It could be an
> MMIO one with an MFN which simply has no associated struct page_info.
I'll address that in the v3. I also found that I cannot use guest_remove_page()
for foreign. Foreign pages have a cleanup in the insertion path through
p2m_set_entry.

~Michal




 


Rackspace

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