Page MenuHomeFreeBSD

stand: userboot: improve userdisk error handling
ClosedPublic

Authored by novel on Aug 29 2026, 6:49 AM.
Tags
None
Referenced Files
F175595680: D59262.id185375.diff
Sun, Oct 11, 10:25 PM
F175545141: D59262.id188449.diff
Sun, Oct 11, 2:57 PM
Unknown Object (File)
Sat, Oct 10, 4:56 PM
Unknown Object (File)
Sat, Oct 10, 9:48 AM
Unknown Object (File)
Sat, Oct 10, 9:21 AM
Unknown Object (File)
Sat, Oct 10, 7:48 AM
Unknown Object (File)
Sat, Oct 10, 5:40 AM
Unknown Object (File)
Fri, Oct 9, 7:43 PM
Subscribers

Details

Summary

Currently, userdisk_init() iterates through disks and
checks whether DIOCGSECTORSIZE and DIOCGMEDIASIZE ioctls
are available for the device. If either ioctl fails, userdisk_init()
returns ENXIO with ud_info only partially initialized.
devinit() records the failure, but loader_main() ignores
devinit()'s return value, so later code may access an
uninitialized entry.

In certain cases this code can still boot from a disk even if
userdisk_init() returns ENXIO, for example, when the first of
two disks is valid and the second errors out.

To address this issue while not breaking the current behavior, do
the following:

  • Zero-initialize the userdisk_info array and use a zero media size to mark disks that do not support the ioctls mentioned above or report an empty medium.
  • Update userdisk_print() not to print unusable disks.
  • Update userdisk_open() to return EIO for unusable disks.
  • Update extract_currdev() to pick the first usable disk instead of the first disk. Introduce userboot_disk_firstunit() for that.

Additionally, reset counters on ud_info allocation failure to prevent
accessing unallocated data.

Diff Detail

Repository
rG FreeBSD src repository
Lint
Lint Not Applicable
Unit
Tests Not Applicable

Event Timeline

novel requested review of this revision.Aug 29 2026, 6:49 AM

My only other thought in addition to the memset() suggestion is maybe treating mediasize == 0 as ud_usable == false vs adding a new field.

stand/userboot/userboot/userboot_disk.c
88–89

Can we use calloc() here, or if not, memset the array to zero after the allocation? That will simplify initialization a bit I think (and ensure the values are always deterministic).

96

With the memset suggestion above you can trim some of the assignments, and possibly refactor as:

if (CALLBACK(...) == 0) {
    ud_info[i].mediasize = mediasize;
    ud_info[i[.sectorsize = sectorsize;
    ud_info[i].ud_usable = true;
    userdisk_usable++;
}
  • Replace malloc() with calloc() and simplify code a bit.
  • Revert adding of the new 'ud_usable' field to the 'userdisk_info' struct, consider disk usable when 'mediasize != 0'.
novel marked 2 inline comments as done.Fri, Oct 2, 5:25 PM
novel edited the summary of this revision. (Show Details)
This revision is now accepted and ready to land.Mon, Oct 5, 1:13 PM