Page MenuHomeFreeBSD

D47359.id145765.diff
No OneTemporary

D47359.id145765.diff

diff --git a/sys/kern/subr_bus.c b/sys/kern/subr_bus.c
--- a/sys/kern/subr_bus.c
+++ b/sys/kern/subr_bus.c
@@ -1121,7 +1121,8 @@
* @brief Find a free unit number in a devclass
*
* This function searches for the first unused unit number greater
- * that or equal to @p unit.
+ * that or equal to @p unit. Note: This can return INT_MAX which
+ * may be rejected elsewhere.
*
* @param dc the devclass to examine
* @param unit the first unit number to check
@@ -1188,6 +1189,7 @@
* @retval 0 success
* @retval EEXIST the requested unit number is already allocated
* @retval ENOMEM memory allocation failure
+ * @retval EINVAL unit is negative or we've run out of units
*/
static int
devclass_alloc_unit(devclass_t dc, device_t dev, int *unitp)
@@ -1202,10 +1204,13 @@
BUS_HINT_DEVICE_UNIT(device_get_parent(dev), dev, dc->name,
&unit);
+ /* Unit numbers are either DEVICE_UNIT_ANY or in [0,INT_MAX) */
+ if ((unit < 0 && unit != DEVICE_UNIT_ANY) || unit == INT_MAX)
+ return (EINVAL);
+
/* If we were given a wired unit number, check for existing device */
if (unit != DEVICE_UNIT_ANY) {
- if (unit >= 0 && unit < dc->maxunit &&
- dc->devices[unit] != NULL) {
+ if (unit < dc->maxunit && dc->devices[unit] != NULL) {
if (bootverbose)
printf("%s: %s%d already exists; skipping it\n",
dc->name, dc->name, *unitp);
@@ -1214,7 +1219,7 @@
} else {
/* Unwired device, find the next available slot for it */
unit = 0;
- for (unit = 0;; unit++) {
+ for (unit = 0; unit < INT_MAX; unit++) {
/* If this device slot is already in use, skip it. */
if (unit < dc->maxunit && dc->devices[unit] != NULL)
continue;
@@ -1228,6 +1233,15 @@
}
}
+ /*
+ * Unit numbers must be in the range [0, INT_MAX), so exclude INT_MAX as
+ * too large. We constrain maxunit below to be <= INT_MAX. This means we
+ * can treat unit and maxunit as normal integers with normal math
+ * everywhere and we only have to flag INT_MAX as invalid.
+ */
+ if (unit == INT_MAX)
+ return (EINVAL);
+
/*
* We've selected a unit beyond the length of the table, so let's
* extend the table to make room for all units up to and including
@@ -1238,8 +1252,8 @@
int newsize;
oldlist = dc->devices;
- newsize = roundup((unit + 1),
- MAX(1, MINALLOCSIZE / sizeof(device_t)));
+ newsize = MIN(INT_MAX, roundup((unit + 1),
+ MAX(1, MINALLOCSIZE / sizeof(device_t))));
newlist = malloc(sizeof(device_t) * newsize, M_BUS, M_NOWAIT);
if (!newlist)
return (ENOMEM);
@@ -1273,6 +1287,7 @@
* @retval 0 success
* @retval EEXIST the requested unit number is already allocated
* @retval ENOMEM memory allocation failure
+ * @retval EINVAL Unit number invalid or too many units
*/
static int
devclass_add_device(devclass_t dc, device_t dev)

File Metadata

Mime Type
text/plain
Expires
Sun, Apr 12, 5:03 PM (13 h, 21 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
31360219
Default Alt Text
D47359.id145765.diff (2 KB)

Event Timeline