summaryrefslogtreecommitdiffstats
path: root/Incremental.c
diff options
context:
space:
mode:
authorNeilBrown <neilb@suse.de>2009-04-07 17:54:09 +1000
committerNeilBrown <neilb@suse.de>2009-04-07 17:54:09 +1000
commit7c5483270d39599361a69de11f1b8debafde03a9 (patch)
tree8407f174bee9216cbbfdd09bc4e423cd3d1ecfb2 /Incremental.c
parent7f15ccce537c4e07ce8e1919684f3d4e4feabc9e (diff)
downloadmdadm-7c5483270d39599361a69de11f1b8debafde03a9.tar.gz
mdadm-7c5483270d39599361a69de11f1b8debafde03a9.tar.xz
mdadm-7c5483270d39599361a69de11f1b8debafde03a9.zip
Incremental - avoid NULL dereference.
There structure returned by sysfs_read might not have any 'devs', don't assume it does. Signed-off-by: NeilBrown <neilb@suse.de>
Diffstat (limited to 'Incremental.c')
-rw-r--r--Incremental.c52
1 files changed, 27 insertions, 25 deletions
diff --git a/Incremental.c b/Incremental.c
index 1e74da6..f7e602e 100644
--- a/Incremental.c
+++ b/Incremental.c
@@ -335,32 +335,34 @@ int Incremental(char *devname, int verbose, int runstop,
sra = sysfs_read(mdfd, fd2devnum(mdfd), (GET_DEVS | GET_STATE));
- sprintf(dn, "%d:%d", sra->devs->disk.major,
- sra->devs->disk.minor);
- dfd2 = dev_open(dn, O_RDONLY);
- st2 = dup_super(st);
- if (st2->ss->load_super(st2, dfd2, NULL) ||
- st->ss->compare_super(st, st2) != 0) {
- fprintf(stderr, Name
- ": metadata mismatch between %s and "
- "chosen array %s\n",
- devname, chosen_name);
- close(mdfd);
+ if (sra->devs) {
+ sprintf(dn, "%d:%d", sra->devs->disk.major,
+ sra->devs->disk.minor);
+ dfd2 = dev_open(dn, O_RDONLY);
+ st2 = dup_super(st);
+ if (st2->ss->load_super(st2, dfd2, NULL) ||
+ st->ss->compare_super(st, st2) != 0) {
+ fprintf(stderr, Name
+ ": metadata mismatch between %s and "
+ "chosen array %s\n",
+ devname, chosen_name);
+ close(mdfd);
+ close(dfd2);
+ return 2;
+ }
close(dfd2);
- return 2;
- }
- close(dfd2);
- memset(&info2, 0, sizeof(info2));
- st2->ss->getinfo_super(st2, &info2);
- st2->ss->free_super(st2);
- if (info.array.level != info2.array.level ||
- memcmp(info.uuid, info2.uuid, 16) != 0 ||
- info.array.raid_disks != info2.array.raid_disks) {
- fprintf(stderr, Name
- ": unexpected difference between %s and %s.\n",
- chosen_name, devname);
- close(mdfd);
- return 2;
+ memset(&info2, 0, sizeof(info2));
+ st2->ss->getinfo_super(st2, &info2);
+ st2->ss->free_super(st2);
+ if (info.array.level != info2.array.level ||
+ memcmp(info.uuid, info2.uuid, 16) != 0 ||
+ info.array.raid_disks != info2.array.raid_disks) {
+ fprintf(stderr, Name
+ ": unexpected difference between %s and %s.\n",
+ chosen_name, devname);
+ close(mdfd);
+ return 2;
+ }
}
info2.disk.major = major(stb.st_rdev);
info2.disk.minor = minor(stb.st_rdev);