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 @@ -5303,27 +5303,37 @@ bus_data_generation_update(); } -static char * -device_get_path(device_t dev, const char *locator) +static int +device_get_path(device_t dev, const char *locator, char **rvp) { struct sbuf *sb; + char *s; + device_t parent; ssize_t len; - char *rv = NULL; int error; sb = sbuf_new(NULL, NULL, 0, SBUF_AUTOEXTEND | SBUF_INCLUDENUL); - error = BUS_GET_DEVICE_PATH(device_get_parent(dev), dev, locator, sb); + parent = device_get_parent(dev); + if (parent == NULL) + parent = dev; + error = BUS_GET_DEVICE_PATH(parent, dev, locator, sb); sbuf_finish(sb); /* Note: errors checked with sbuf_len() below */ - if (error != 0) - goto out; - len = sbuf_len(sb); - if (len <= 1) - goto out; - rv = malloc(len, M_BUS, M_NOWAIT); - memcpy(rv, sbuf_data(sb), len); -out: + if (error == 0) { + len = sbuf_len(sb); + if (len <= 1) { + error = EIO; + } else { + s = malloc(len, M_BUS, M_NOWAIT); + if (s == NULL) { + error = ENOMEM; + } else { + memcpy(s, sbuf_data(sb), len); + *rvp = s; + } + } + } sbuf_delete(sb); - return (rv); + return (error); } static int @@ -5590,14 +5600,13 @@ char *path; ssize_t len; - error = copyinstr(req->dr_buffer.buffer, locator, sizeof(locator), NULL); - if (error) + error = copyinstr(req->dr_buffer.buffer, locator, + sizeof(locator), NULL); + if (error != 0) break; - path = device_get_path(dev, locator); - if (path == NULL) { - error = ENOMEM; + error = device_get_path(dev, locator, &path); + if (error != 0) break; - } len = strlen(path) + 1; if (req->dr_buffer.length < len) { error = ENAMETOOLONG; @@ -5699,9 +5708,10 @@ bool dev_wired_cache_match(device_location_cache_t *dcp, device_t dev, const char *at) { - const char *cp, *path; + const char *cp; + char *path; char locator[32]; - int len; + int error, len; struct device_location_node *res; cp = strchr(at, ':'); @@ -5714,13 +5724,15 @@ locator[len] = '\0'; cp++; + error = 0; /* maybe cache this inside device_t and look that up, but not yet */ res = dev_wired_cache_lookup(dcp, locator); if (res == NULL) { - path = device_get_path(dev, locator); - res = dev_wired_cache_add(dcp, locator, path); + error = device_get_path(dev, locator, &path); + if (error == 0) + res = dev_wired_cache_add(dcp, locator, path); } - if (res == NULL || res->dln_path == NULL) + if (error != 0 || res == NULL || res->dln_path == NULL) return (false); return (strcmp(res->dln_path, cp) == 0);