> Date: Mon, 9 Nov 2020 14:18:03 +0000
> From: Stuart Henderson <[email protected]>
>
> On 2020/11/08 11:42, Benjamin Baier wrote:
> > Forwarding to tech@ by request from Stuart Henderson
> > This issue came up on misc@
> > https://marc.info/?l=openbsd-misc&m=160477082230840&w=2
> >
> > Begin forwarded message:
> >
> > Date: Sat, 7 Nov 2020 22:30:44 +0100
> > From: Benjamin Baier <[email protected]>
> > To: Bruce Lilly <[email protected]>
> > Cc: [email protected]
> > Subject: Re: Hardware UUID discrepancies (dmidecode vs. sysctl) on amd64
> > multiboot system
> >
> >
> > On Sat, 7 Nov 2020 12:36:42 -0500
> > Bruce Lilly <[email protected]> wrote:
> >
> > > I have a multiboot system with several OSes on the same hardware.
> > >
> > > Summary: OpenBSD UUID reported by dmidecode and from sysctl differ
> > > significantly w.r.t. byte ordering. Multiple OSes report the same
> > > dmidecode
> > > UUID, and most other OSes provide one or more alternate ways of accessing
> > > the UUID which yields results consistent with dmidecode.
> > >
> > > Details:
> > > dmidecode (after fiddling with kern.allowkmem via /etc/sysctl.conf on
> > > OpenBSD)
> > > run on each OS that has a dmidecode utility reports the same hardware UUID
> > > (modulo hexadecimal digit case), viz.
> > >
> > > UUID: 484B1340-D7AA-81E5-3CED-9C5C8E3D6756
> > >
> > > OpenBSD (6.8) `sysctl hw.uuid` instead reports:
> > >
> > > hw.uuid=40134b48-aad7-e581-3ced-9c5c8e3d6756
> > >
> > > Note that the differences are:
> > > 1. case of hexadecimal digits (inconsequential)
> > > 2. byte ordering (but inconsistently so between the initial part
> > > and the last 64 bits (the latter part's byte ordering is consistent
> > > with dmidecode))
> > >
> > According to SMBIOS Reference Specification, you are correct.
> > 7.2.1
> > Although RFC 4122 recommends network byte order for all fields, the PC
> > industry (including the ACPI,
> > UEFI, and Microsoft specifications) has consistently used little-endian
> > byte encoding for the first three
> > fields: time_low, time_mid, time_hi_and_version. The same encoding, also
> > known as wire format, should
> > also be used for the SMBIOS representation of the UUID.
> > The UUID {00112233-4455-6677-8899-AABBCCDDEEFF} would thus be represented
> > as:
> > 33 22 11 00 55 44 77 66 88 99 AA BB CC DD EE FF.
> >
> > What are the ramifications of a changed UUID?
> > What software depends on hw.uuid not changing?
> >
> > Greetings Ben
> >
> > ---
>
> I think it would be correct to change our code to follow the spec,
> but reading the manual of current versions of dmidecode it goes a bit
> further;
>
> There is some ambiguity about how to interpret the UUID fields
> prior to SMBIOS specification version 2.6. There was no mention
> of byte swapping, and RFC 4122 says that no byte swapping should
> be applied by default. However, SMBIOS specification version
> 2.6 (and later) explicitly states that the first 3 fields of
> the UUID should be read as little-endian numbers (byte-swapped).
> Furthermore, it implies that the same was already true for older
> versions of the specification, even though it was not mentioned.
> In practice, many hardware vendors were not byte-swapping the
> UUID. So, in order to preserve compatibility, it was decided
> to interpret the UUID fields according to RFC 4122 (no byte
> swapping) when the SMBIOS version is older than 2.6, and to
> interpret the first 3 fields as little-endian (byte-swapped)
> when the SMBIOS version is 2.6 or later. The Linux kernel follows
> the same logic.
>
> It would seem sensible to follow that lead here I think? Diff for that
> below.
>
> I don't think many people will be making existing use of hw.uuid but it
> is possible, I don't think there's much we can do other than mention it
> in upgrade notes.
Given that explanation, I'd argue that we should leave things as-is.
Folks interpreted the standard differently and in the end our
interpretation won. Adding more code to "fix" this issue doesn't make
a lot of sense to me. Besides, where in the documentation is it
spelled out that hw.uuid matches the SMBIOS UUID?
> Index: amd64/amd64/bios.c
> ===================================================================
> RCS file: /cvs/src/sys/arch/amd64/amd64/bios.c,v
> retrieving revision 1.43
> diff -u -p -u -2 -5 -r1.43 bios.c
> --- amd64/amd64/bios.c 26 Aug 2020 03:29:05 -0000 1.43
> +++ amd64/amd64/bios.c 9 Nov 2020 14:14:18 -0000
> @@ -476,30 +476,45 @@ smbios_info(char *str)
> strlcpy(hw_serial, sminfop, infolen);
> }
> if (smbios_entry.mjr > 2 || (smbios_entry.mjr == 2 &&
> smbios_entry.min >= 1)) {
> /*
> * If the uuid value is all 0xff the uuid is present but not
> * set, if its all 0 then the uuid isn't present at all.
> */
> uuidf = SMBIOS_UUID_NPRESENT|SMBIOS_UUID_NSET;
> for (i = 0; i < sizeof(sys->uuid); i++) {
> if (sys->uuid[i] != 0xff)
> uuidf &= ~SMBIOS_UUID_NSET;
> if (sys->uuid[i] != 0)
> uuidf &= ~SMBIOS_UUID_NPRESENT;
> }
>
> if (uuidf & SMBIOS_UUID_NPRESENT)
> hw_uuid = NULL;
> else if (uuidf & SMBIOS_UUID_NSET)
> hw_uuid = "Not Set";
> else {
> for (i = 0; i < sizeof(sys->uuid); i++)
> enqueue_randomness(sys->uuid[i]);
> hw_uuid = malloc(SMBIOS_UUID_REPLEN, M_DEVBUF,
> M_NOWAIT);
> - if (hw_uuid) {
> + /*
> + * SMBIOS specification 2.6 states that the first 3
> + * fields of the UUID should be read as little-endian
> + * numbers; earlier versions did not mention this.
> + */
> + if (hw_uuid && (smbios_entry.mjr > 2 ||
> + smbios_entry.min >= 6)) {
> + snprintf(hw_uuid, SMBIOS_UUID_REPLEN,
> + SMBIOS_UUID_REP,
> + sys->uuid[3], sys->uuid[2], sys->uuid[1],
> + sys->uuid[0], sys->uuid[5], sys->uuid[4],
> + sys->uuid[7], sys->uuid[6], sys->uuid[8],
> + sys->uuid[9], sys->uuid[10], sys->uuid[11],
> + sys->uuid[12], sys->uuid[13], sys->uuid[14],
> + sys->uuid[15]);
> + } else if (hw_uuid) {
> snprintf(hw_uuid, SMBIOS_UUID_REPLEN,
> SMBIOS_UUID_REP,
> sys->uuid[0], sys->uuid[1], sys->uuid[2],
> sys->uuid[3], sys->uuid[4], sys->uuid[5],
> Index: arm64/dev/smbios.c
> ===================================================================
> RCS file: /cvs/src/sys/arch/arm64/dev/smbios.c,v
> retrieving revision 1.6
> diff -u -p -r1.6 smbios.c
> --- arm64/dev/smbios.c 26 Aug 2020 03:29:05 -0000 1.6
> +++ arm64/dev/smbios.c 9 Nov 2020 14:10:48 -0000
> @@ -407,7 +407,22 @@ smbios_info(char *str)
> enqueue_randomness(sys->uuid[i]);
> hw_uuid = malloc(SMBIOS_UUID_REPLEN, M_DEVBUF,
> M_NOWAIT);
> - if (hw_uuid) {
> + /*
> + * SMBIOS specification 2.6 states that the first 3
> + * fields of the UUID should be read as little-endian
> + * numbers; earlier versions did not mention this.
> + */
> + if (hw_uuid && (smbios_entry.mjr > 2 ||
> + smbios_entry.min >= 6)) {
> + snprintf(hw_uuid, SMBIOS_UUID_REPLEN,
> + SMBIOS_UUID_REP,
> + sys->uuid[3], sys->uuid[2], sys->uuid[1],
> + sys->uuid[0], sys->uuid[5], sys->uuid[4],
> + sys->uuid[7], sys->uuid[6], sys->uuid[8],
> + sys->uuid[9], sys->uuid[10], sys->uuid[11],
> + sys->uuid[12], sys->uuid[13], sys->uuid[14],
> + sys->uuid[15]);
> + } else if (hw_uuid) {
> snprintf(hw_uuid, SMBIOS_UUID_REPLEN,
> SMBIOS_UUID_REP,
> sys->uuid[0], sys->uuid[1], sys->uuid[2],
> Index: i386/i386/bios.c
> ===================================================================
> RCS file: /cvs/src/sys/arch/i386/i386/bios.c,v
> retrieving revision 1.126
> diff -u -p -r1.126 bios.c
> --- i386/i386/bios.c 26 Aug 2020 03:29:05 -0000 1.126
> +++ i386/i386/bios.c 9 Nov 2020 14:10:48 -0000
> @@ -1077,7 +1077,22 @@ smbios_info(char *str)
> enqueue_randomness(sys->uuid[i]);
> hw_uuid = malloc(SMBIOS_UUID_REPLEN, M_DEVBUF,
> M_NOWAIT);
> - if (hw_uuid) {
> + /*
> + * SMBIOS specification 2.6 states that the first 3
> + * fields of the UUID should be read as little-endian
> + * numbers; earlier versions did not mention this.
> + */
> + if (hw_uuid && (smbios_entry.mjr > 2 ||
> + smbios_entry.min >= 6)) {
> + snprintf(hw_uuid, SMBIOS_UUID_REPLEN,
> + SMBIOS_UUID_REP,
> + sys->uuid[3], sys->uuid[2], sys->uuid[1],
> + sys->uuid[0], sys->uuid[5], sys->uuid[4],
> + sys->uuid[7], sys->uuid[6], sys->uuid[8],
> + sys->uuid[9], sys->uuid[10], sys->uuid[11],
> + sys->uuid[12], sys->uuid[13], sys->uuid[14],
> + sys->uuid[15]);
> + } else if (hw_uuid) {
> snprintf(hw_uuid, SMBIOS_UUID_REPLEN,
> SMBIOS_UUID_REP,
> sys->uuid[0], sys->uuid[1], sys->uuid[2],
>
>