The issue is still there in 2023.
Well since XP's source code had been leaked. I've gone through the source code 
and may have found the cause.

Nowadays UuidCreateSequential should use MAC address when available.
Here I quoted from the link below:
"For security reasons, UuidCreate was modified so that it no longer uses a 
machine's MAC address to generate UUIDs. UuidCreateSequential was introduced to 
allow creation of UUIDs using the MAC address of a machine's Ethernet card."
https://learn.microsoft.com/en-us/windows/win32/api/rpcdce/nf-rpcdce-uuidcreatesequential

Now let take a look at XP's code:
uuid.c:
https://github.com/tongzx/nt5src/blob/daad8a087a4e75422ec96b7911f1df4669989611/Source/XPSP1/NT/base/ntos/ex/uuid.c#L545
/*++

Copyright (c) 1994-1997  Microsoft Corporation

Module Name:

    uuid.c

Abstract:

    This module implements the core time and sequence number allocation
    for UUIDs (exposed to user mode), as well as complete UUID
    creation (exposed to kernel mode only).

              (e.g. RPC Runtime)                (e.g. NTFS)
                      |                              |
                      V                              V
                NtAllocateUuids                 ExUuidCreate
                      |                              |
                      V                              V
                      |                         ExpUuidGetValues
                      |                              |
                      |                              |
                      +------> ExpAllocateUuids <----+


start.cxx:
https://github.com/tongzx/nt5src/blob/daad8a087a4e75422ec96b7911f1df4669989611/Source/XPSP1/NT/com/ole32/dcomss/wrapper/start.cxx#L282C23-L282C41

NtSetUuidSeed (
    IN PCHAR Seed
    )
/*++

Routine Description:

    This routine is used to set the seed used for UUID generation. The seed
    will be set by RPCSS at startup and each time a card is replaced.

Arguments:

    Seed - Pointer to a six byte buffer

Return Value:

    STATUS_SUCCESS is returned if the service is successfully executed.

    STATUS_ACCESS_DENIED If caller doesn't have the permissions to make this 
call.
    You need to be logged on as Local System in order to call this API.

    STATUS_ACCESS_VIOLATION is returned if the Seed could not be read.

--*/


/*++

Copyright (c) 1995 Microsoft Corporation

Module Name:

    Start.c

Abstract:

    Process init and service controller interaction for dcomss.exe

Author:

    Mario Goertzel    [MarioGo]

Revision History:

    MarioGo    06-14-95    Cloned from the old endpoint mapper.
    MazharM    10-12.98    Add pnp stuff
    TarunA     12-11-98    Removed pnpmngr.h
    a-sergiv   25-08-99    Defined gC2Security for process-wide use

--*/
DealWithDeviceEvent()
/*++
Function Name: DealWithDeviceEvent

Parameters:

Description:

Returns:

--*/
{
    UCHAR MacAddress[8];
    NTSTATUS NtStatus;

    if (getMacAddress(&MacAddress[0]))
        {
        NtStatus = NtSetUuidSeed((PCHAR) &MacAddress[0]);
        }
    else
        {
        CookupNodeId(&MacAddress[0]);

        ASSERT(MacAddress[0] & 0x80);

        NtStatus = NtSetUuidSeed((PCHAR) &MacAddress[0]);
        }

    if (!NT_SUCCESS(NtStatus))
        {
        #if DBG
        DbgPrint("NtSetUuidSeed failed\n", NtStatus);
        #endif
        }

#if !defined(SPX_IPX_OFF)
    UpdateSap( SAP_CTRL_UPDATE_ADDRESS );
#endif
}


getMacAddress (
    PUCHAR pMacAddress
    )
/*++
Function Name:getMacAddress

Parameters:

Description:

Returns:

--*/
{
    int i;
    UINT fStatus;
    int Size = 1024*5;
    PNDIS_ENUM_INTF Interfaces;
    UCHAR       OidVendData[16];

    Interfaces = (PNDIS_ENUM_INTF) I_RpcAllocate (Size);
    if (Interfaces == 0)
        {
        return FALSE;
        }

    if (NdisEnumerateInterfaces(Interfaces, Size))
        {
        UINT i;

        for (i = 0; i < Interfaces->TotalInterfaces; i++)
            {
            PUNICODE_STRING pDeviceName= &(Interfaces->Interface[i].DeviceName);
            UCHAR           PermMacAddr[6];

            fStatus = NdisQueryHwAddress(pDeviceName, pMacAddress, PermMacAddr, 
&OidVendData[0]);
            if (fStatus && (OidVendData[0] != 0xFF
                || OidVendData[1] != 0xFF
                || OidVendData[2] != 0xFF))
                {
                I_RpcFree (Interfaces);

                return TRUE;
                }
            }
        }

    I_RpcFree (Interfaces);

    return FALSE;
}

As see can see functions realted to UuidCreateSequential(it use the seed
ad the last 48 bits of uuid), the following code showed how Windows
obtain MAC address and OidVendorData, if OidVendorData's first 6 bytes
is 0xff, the function will fail, casing a random value generated rather
than the mac of our adapter. So I guess its related to the virtio
implementation. But I can't identify where the OidVendData is defined.
So I think I should file a issue to virtio dev teams too.

            fStatus = NdisQueryHwAddress(pDeviceName, pMacAddress, PermMacAddr, 
&OidVendData[0]);
            if (fStatus && (OidVendData[0] != 0xFF
                || OidVendData[1] != 0xFF
                || OidVendData[2] != 0xFF))
                {
                I_RpcFree (Interfaces);

                return TRUE;
                }
            }

-- 
You received this bug notification because you are a member of qemu-
devel-ml, which is subscribed to QEMU.
https://bugs.launchpad.net/bugs/1119281

Title:
  The virtio network device breaks UuidCreateSequential()

Status in QEMU:
  Expired

Bug description:
  UuidCreateSequential() usually creates version 1 UUIDs (1) which means
  they contain the main network card's MAC address. However when using a
  virtio network card and driver the UUIDs contain random data instead
  of the guest's MAC address. Changing the network card to either the
  default rtl8139 one or the e1000 one fixes the issue.

  Here is the software I have tested this with:
   * qemu 1.1.2+dfsg-5 and 1.4.0~rc0+dfsg-1exp (from Debian Testing and 
Experimental respectively)
   * The 0.1-49 and 0.1-52 Windows virtio drivers from 
https://alt.fedoraproject.org/pub/alt/virtio-win/latest/images/bin/
   * Both a 32-bit Windows XP guest and a 64-bit Windows 7 one.

  
  Here is how to test for this issue:
  * Set up a Windows guest with a single network card(2), a virtio one and 
install the corresponding driver.

  * Boot the guest and copy the uuidtest.exe file (see attachement) to
  it

  * On the command line, type 'ipconfig /all'. Give you the correct
  network card's MAC address on a line like the one below:

          Physical Address. . . . . . . . . : 52-54-00-C7-0E-97

  * Run uuidtest.exe. It will show the VM returning a UUID with the
  wrong MAC address, and quite possibly even a multicast MAC address!
  (3). In the example below 'f75292c62787' should have been the MAC
  address. Note that on Windows XP UuidCreateSequential() returns
  RPC_S_UUID_LOCAL_ONLY for virtio cards but that on Windows 7 it
  returns 0.

          UuidCreateSequential() returned 0
          uuid={56e1ffe4-71d8-11e2-b1cc-f75292c62787}
          Got a version 1 UUID
          The UUID does not contain a non-multicast MAC address

  * Reboot and notice uuidtest.exe now reports a different value where
  the MAC address should be.

  * Shut down the VM and switch the network card to rtl8139, install the
  drivers, run uuidtest.exe and notice that the last group of digits
  finally contains the correct MAC address.

  
  (1) https://en.wikipedia.org/wiki/Globally_unique_identifier#Algorithm
  (2) Best do it with a single card to avoid confusion over which is the 
primary one.
  (3) If the first byte of the address is odd then this is a multicast address.
      https://en.wikipedia.org/wiki/MAC_address#Address_details

To manage notifications about this bug go to:
https://bugs.launchpad.net/qemu/+bug/1119281/+subscriptions


Reply via email to