On Wed, 21 Aug 2019, Eugene Grosbein wrote:

21.08.2019 3:12, FreeBSD Security Advisories wrote:

[skip]

IV.  Workaround

No workaround is available.  Custom kernels without "device sound"
are not vulnerable.

Is it true that there is no way to disable vulnerable and unneeded device driver
built in GENERIC other that through rebuilding the kernel?

I remember that pre-4.x versions of FreeBSD had visual VGA-based pre-boot 
configurator

Visual userconfig and command-line userconfug were in all versions of 4.x
too.

allowing to disable any compiled-in device driver. Don't device.hints(5) or 
loader(8) have means to do so?

Configuration was unimproved by hints, env and new-bus after 4.x.  In
4.x and earlier, the irq and other parameters, and disable and other
flags, were part of a formal syntax implemented at config(8) time using
yacc and at kernel userconfig time more hackishly and at kernel visual
userconfig time more guishlly.  Now hints and env give a random mostly
undocumented syntax.  Even disable flags don't work right.  New-bus
allows more complicated or just larger topologies which are harder to
control using disable flags.

These days GENERIC have LOTS of drivers and it's convenient but unsafe.

It is hard to even find the list of (unattached) drivers, or get useful
(fauling) probe messages for drivers that aren't used.

I use the following patch mainly to fix sio and uart probing in uncontrollable
or hard-coded order and/or precendence when both are statically configured.
One must be disabled on a per-device basis, but even disabling doesn't work
without this patch.

The patch preserves some historical mistakes and adds some excessive
verboseness about probe failures.  I'm still waiting for jhb to reply to
mails on 30 Oct 2015 and 23 Jan 2018 asking for a review of this patch
or better a complete fix.

XX Index: subr_bus.c
XX ===================================================================
XX --- subr_bus.c       (revision 332488)
XX +++ subr_bus.c       (working copy)
XX @@ -2079,6 +2079,12 @@
XX      return (TAILQ_NEXT(last, link));
XX  }
XX XX +/*
XX + * Keep probing disabled devices for now, in case this has beneficial side
XX + * effects.
XX + */
XX +static volatile int probe_rdisabled = 0;
XX +
XX  /**
XX   * @internal
XX   */
XX @@ -2088,7 +2094,7 @@
XX      devclass_t dc;
XX      driverlink_t best = NULL;
XX      driverlink_t dl;
XX -    int result, pri = 0;
XX +    int rdisabled, result, unit, pri = 0;
XX      int hasclass = (child->devclass != NULL);
XX XX GIANT_REQUIRED;
XX @@ -2139,8 +2145,27 @@
XX                      resource_int_value(dl->driver->name, child->unit,
XX                          "flags", &child->devflags);
XX XX - result = DEVICE_PROBE(child);
XX +                    /* Record other state while the unit is valid. */
XX +                    unit = child->unit;
XX +                    rdisabled = resource_disabled(dl->driver->name, unit);
XX XX + /* See below for more details. */
XX +                    if (rdisabled) {
XX +                            device_print_prettyname(dev);
XX +                            if (probe_rdisabled)
XX +                                    device_printf(child,
XX +                                        "probing disabled device\n");
XX +                            else {
XX +                                    device_printf(child,
XX +                                        "disabled in probe by hints\n");
XX +                                    device_disable(child);
XX +                            }
XX +                    }
XX +                    if (rdisabled && !probe_rdisabled)
XX +                            result = ENXIO;
XX +                    else
XX +                            result = DEVICE_PROBE(child);
XX +
XX                      /* Reset flags and devclass before the next probe. */
XX                      child->devflags = 0;
XX                      if (!hasclass)
XX @@ -2182,6 +2207,30 @@
XX                      }
XX XX /*
XX +                     * Ignore the result of probing a disabled device,
XX +                     * so that disabled devices with higher priorities
XX +                     * are not preferred, only to do nothing at attach
XX +                     * time but complete their disablement and fail.
XX +                     * This is not quite right since it loses the
XX +                     * accidental (?) feature of being able to disable
XX +                     * attaching a resource for all drivers by
XX +                     * disabling it for one driver if there happens to
XX +                     * one with highest priority (or equal highest,
XX +                     * with the disabled one preferred because it is
XX +                     * probed first.
XX +                     */
XX +                    if (rdisabled) {
XX +                            device_print_prettyname(dev);
XX +                            /* XXX device_printf() fails -- child inval. */
XX +                            printf("%s%d: disabled in probe by hints\n",
XX +                                dl->driver->name, unit);
XX +#ifdef notyet /* XXX don't risk this with invalid child->unit */
XX +                            device_disable(child);
XX +#endif
XX +                            continue;
XX +                    }
XX +
XX +                    /*
XX                       * A priority lower than SUCCESS, remember the
XX                       * best matching driver. Initialise the value
XX                       * of pri for the first match.

The rest is unrelated (keep the message out of the attach timing).  But
it seems reasonable to get entropy from probe time as well as attach
timing, and that would include timing for spammish probe messages.

XX @@ -2909,8 +2958,6 @@
XX      }
XX XX device_sysctl_init(dev);
XX -    if (!device_is_quiet(dev))
XX -            device_print_child(dev->parent, dev);
XX      attachtime = get_cyclecount();
XX      dev->state = DS_ATTACHING;
XX      if ((error = DEVICE_ATTACH(dev)) != 0) {
XX @@ -2925,6 +2972,8 @@
XX              return (error);
XX      }
XX      attachtime = get_cyclecount() - attachtime;
XX +    if (!device_is_quiet(dev))
XX +            device_print_child(dev->parent, dev);
XX      /*
XX       * 4 bits per device is a reasonable value for desktop and server
XX       * hardware with good get_cyclecount() implementations, but WILL

Bruce
_______________________________________________
freebsd-security@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/freebsd-security
To unsubscribe, send any mail to "freebsd-security-unsubscr...@freebsd.org"

Reply via email to