diff options
author | Dan Williams <dan.j.williams@intel.com> | 2010-06-16 17:26:04 -0700 |
---|---|---|
committer | Dan Williams <dan.j.williams@intel.com> | 2010-06-16 17:26:04 -0700 |
commit | b526e52dc7cbdde98db9c9f8765be28ba6d71d78 (patch) | |
tree | c9c303fc940a4da78996d26f829271913fe8b730 /sysfs.c | |
parent | fd547b508c90a647cf60df678047f07046cf5c68 (diff) | |
download | mdadm-b526e52dc7cbdde98db9c9f8765be28ba6d71d78.tar.gz mdadm-b526e52dc7cbdde98db9c9f8765be28ba6d71d78.tar.xz mdadm-b526e52dc7cbdde98db9c9f8765be28ba6d71d78.zip |
Always assume SKIP_GONE_DEVS behaviour and kill the flag
...i.e. GET_DEVS == (GET_DEVS|SKIP_GONE_DEVS)
A null pointer dereference in Incremental.c can be triggered by
replugging a disk while the old name is in use. When mdadm -I is called
on the new disk we fail the call to sysfs_read(). I audited all the
locations that use GET_DEVS and it appears they can tolerate missing a
drive. So just make SKIP_GONE_DEVS the default behaviour.
Also fix up remaining unchecked usages of the sysfs_read() return value.
Reported-by: Dave Jiang <dave.jiang@intel.com>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
Diffstat (limited to 'sysfs.c')
-rw-r--r-- | sysfs.c | 20 |
1 files changed, 9 insertions, 11 deletions
@@ -273,22 +273,20 @@ struct mdinfo *sysfs_read(int fd, int devnum, unsigned long options) strcpy(dbase, "block/dev"); if (load_sys(fname, buf)) { + /* assume this is a stale reference to a hot + * removed device + */ free(dev); - if (options & SKIP_GONE_DEVS) - continue; - else - goto abort; + continue; } sscanf(buf, "%d:%d", &dev->disk.major, &dev->disk.minor); /* special case check for block devices that can go 'offline' */ - if (options & SKIP_GONE_DEVS) { - strcpy(dbase, "block/device/state"); - if (load_sys(fname, buf) == 0 && - strncmp(buf, "offline", 7) == 0) { - free(dev); - continue; - } + strcpy(dbase, "block/device/state"); + if (load_sys(fname, buf) == 0 && + strncmp(buf, "offline", 7) == 0) { + free(dev); + continue; } /* finally add this disk to the array */ |