[Bug 272018] pci_read_vpd() does not always load VPD even when valid VPD exists because of state machine bug

From: <bugzilla-noreply_at_freebsd.org>
Date: Thu, 15 Jun 2023 18:41:33 UTC
https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=272018

--- Comment #1 from Dave Baukus <daveb@spectralogic.com> ---
The state machine to read a device's VPD in pci_vpd_read() has this statement
at the end of the top level switch() statement:

if (cfg->vpd.vpd_ident == NULL || cfg->vpd.vpd_ident[0] == '\0') {
       pci_printf(cfg, "no valid vpd ident found\n");
       state = -2;
}

The issue is the cfg->vpd.vpd_ident[0] == '\0' check.

On the first iteration with state == 0, case 0: if a "name" of 2 is discovered
(name = (byte >> 3) & 0xf) then the code falls into a sub-switch() statement
where if everything else is valid then vpd_ident is allocated:

switch(name)
case 0x2:
    ...
    ...
    ...
    cfg->vpd.vpd_ident = malloc(remain + 1, M_DEVBUF, M_WAITOK);
    i = 0;
    state = 1;
    break;

Now when the code falls out of the top level switch() the above check triggers.
The code has not assigned anything to cfg->vpd.vpd_ident[0]; it is therefore
random luck weather or not a device with valid VPD gets its VPD cached.

My quick hack: assign a characther not '\0' to cfg->vpd.vpd_ident[0] after it
is allocated. It will be overwritten in case 1 of the top level switch() on the
next iteration; I'm sure there's a more elegant solution.

-- 
You are receiving this mail because:
You are the assignee for the bug.