]> git.ipfire.org Git - thirdparty/mdadm.git/commitdiff
add checking of return status on fstat calls
authorNigel Croxon <ncroxon@redhat.com>
Mon, 20 May 2024 13:36:50 +0000 (09:36 -0400)
committerMariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
Tue, 21 May 2024 07:11:31 +0000 (09:11 +0200)
There are a few places we don't check the return status when
calling fstat for success. Clean up the calls by adding a
check before continuing.

Signed-off-by: Nigel Croxon <ncroxon@redhat.com>
Assemble.c
Dump.c
Grow.c
config.c
mdstat.c
super-ddf.c
super-intel.c

index 83dced19cebadad87610e14ee873aa5439d698e4..58dc2c5e7bf0219516aafe8c412fad23d343b3f3 100644 (file)
@@ -652,7 +652,9 @@ static int load_devices(struct devs *devices, char *devmap,
                        /* prepare useful information in info structures */
                        struct stat stb2;
                        int err;
-                       fstat(mdfd, &stb2);
+
+                       if (fstat(mdfd, &stb2) != 0)
+                               goto error;
 
                        if (c->update == UOPT_UUID && !ident->uuid_set)
                                random_uuid((__u8 *)ident->uuid);
@@ -675,13 +677,10 @@ static int load_devices(struct devs *devices, char *devmap,
                                       devname);
                                if (dfd >= 0)
                                        close(dfd);
-                               close(mdfd);
-                               free(devices);
-                               free(devmap);
                                tst->ss->free_super(tst);
                                free(tst);
                                *stp = st;
-                               return -1;
+                               goto error;
                        }
                        tst->ss->getinfo_super(tst, content, devmap + devcnt * content->array.raid_disks);
 
@@ -715,12 +714,9 @@ static int load_devices(struct devs *devices, char *devmap,
                                               map_num(update_options, c->update), tst->ss->name);
                                tst->ss->free_super(tst);
                                free(tst);
-                               close(mdfd);
                                close(dfd);
-                               free(devices);
-                               free(devmap);
                                *stp = st;
-                               return -1;
+                               goto error;
                        }
                        if (c->update == UOPT_UUID &&
                            !ident->uuid_set) {
@@ -751,18 +747,23 @@ static int load_devices(struct devs *devices, char *devmap,
                                       devname);
                                if (dfd >= 0)
                                        close(dfd);
-                               close(mdfd);
-                               free(devices);
-                               free(devmap);
                                tst->ss->free_super(tst);
                                free(tst);
                                *stp = st;
-                               return -1;
+                               goto error;
                        }
                        tst->ss->getinfo_super(tst, content, devmap + devcnt * content->array.raid_disks);
                }
 
-               fstat(dfd, &stb);
+               if (fstat(dfd, &stb) != 0) {
+                       close(dfd);
+                       free(devices);
+                       free(devmap);
+                       tst->ss->free_super(tst);
+                       free(tst);
+                       *stp = st;
+                       return -1;
+               }
                close(dfd);
 
                if (c->verbose > 0)
@@ -842,12 +843,9 @@ static int load_devices(struct devs *devices, char *devmap,
                                       inargv ? "the list" :
                                       "the\n      DEVICE list in mdadm.conf"
                                        );
-                               close(mdfd);
-                               free(devices);
-                               free(devmap);
                                free(best);
                                *stp = st;
-                               return -1;
+                               goto error;
                        }
                        if (best[i] == -1 || (devices[best[i]].i.events
                                              < devices[devcnt].i.events))
@@ -863,6 +861,13 @@ static int load_devices(struct devs *devices, char *devmap,
        *bestp = best;
        *stp = st;
        return devcnt;
+
+error:
+       close(mdfd);
+       free(devices);
+       free(devmap);
+       return -1;
+
 }
 
 static int force_array(struct mdinfo *content,
diff --git a/Dump.c b/Dump.c
index 736bcb608496b355e33f77aa92cbf7f31c2ffe9d..81b94940002141a97901843fe050f2c4c1760c69 100644 (file)
--- a/Dump.c
+++ b/Dump.c
@@ -37,6 +37,7 @@ int Dump_metadata(char *dev, char *dir, struct context *c,
        unsigned long long size;
        DIR *dirp;
        struct dirent *de;
+       int ret = 0;
 
        if (stat(dir, &stb) != 0 ||
            (S_IFMT & stb.st_mode) != S_IFDIR) {
@@ -112,9 +113,15 @@ int Dump_metadata(char *dev, char *dir, struct context *c,
        }
        if (c->verbose >= 0)
                printf("%s saved as %s.\n", dev, fname);
-       fstat(fd, &dstb);
-       close(fd);
+
        close(fl);
+       ret = fstat(fd, &dstb);
+       close(fd);
+       if (ret) {
+               unlink(fname);
+               free(fname);
+               return 1;
+       }
        if ((dstb.st_mode & S_IFMT) != S_IFBLK) {
                /* Not a block device, so cannot create links */
                free(fname);
diff --git a/Grow.c b/Grow.c
index 1923c27c4274d3331b3a5c4a1cc3e31beafca62f..963792d031f74b804110560ff021cbf99005f121 100644 (file)
--- a/Grow.c
+++ b/Grow.c
@@ -1223,13 +1223,14 @@ int reshape_open_backup_file(char *backup_file,
         * way this will not notice, but it is better than
         * nothing.
         */
-       fstat(*fdlist, &stb);
+       if (fstat(*fdlist, &stb) != 0)
+               goto error;
        dev = stb.st_dev;
-       fstat(fd, &stb);
+       if (fstat(fd, &stb) != 0)
+               goto error;
        if (stb.st_rdev == dev) {
                pr_err("backup file must NOT be on the array being reshaped.\n");
-               close(*fdlist);
-               return 0;
+               goto error;
        }
 
        memset(buf, 0, 512);
@@ -1255,6 +1256,9 @@ int reshape_open_backup_file(char *backup_file,
        }
 
        return 1;
+error:
+       close(*fdlist);
+       return 0;
 }
 
 unsigned long compute_backup_blocks(int nchunk, int ochunk,
index b46d71cb3825ad289338a464c01a9a51d6a5e616..612e700d47399af44b61d5095bb38120148a4d84 100644 (file)
--- a/config.c
+++ b/config.c
@@ -949,7 +949,8 @@ void conf_file_or_dir(FILE *f)
        struct dirent *dp;
        struct fname *list = NULL;
 
-       fstat(fileno(f), &st);
+       if (fstat(fileno(f), &st) != 0)
+               return;
        if (S_ISREG(st.st_mode))
                conf_file(f);
        else if (!S_ISDIR(st.st_mode))
index 2fd792c5d56de1ce4547efd3a3c2fcd71ab96a87..e233f094c4805ebca8ba53d0297b8fdeb5f37410 100644 (file)
--- a/mdstat.c
+++ b/mdstat.c
@@ -348,7 +348,8 @@ void mdstat_wait_fd(int fd, const sigset_t *sigmask)
 
        if (fd >= 0) {
                struct stat stb;
-               fstat(fd, &stb);
+               if (fstat(fd, &stb) != 0)
+                       return;
                if ((stb.st_mode & S_IFMT) == S_IFREG)
                        /* Must be a /proc or /sys fd, so expect
                         * POLLPRI
index 21426c753c6dff4d9dfdba152bb2fb8ac503f107..311001c1003c4a29d5790467636dd1a395d6f343 100644 (file)
@@ -1053,7 +1053,10 @@ static int load_ddf_local(int fd, struct ddf_super *super,
                     0);
        dl->devname = devname ? xstrdup(devname) : NULL;
 
-       fstat(fd, &stb);
+       if (fstat(fd, &stb) != 0) {
+               free(dl);
+               return 1;
+       }
        dl->major = major(stb.st_rdev);
        dl->minor = minor(stb.st_rdev);
        dl->next = super->dlist;
@@ -2786,7 +2789,8 @@ static int add_to_super_ddf(struct supertype *st,
        /* This is device numbered dk->number.  We need to create
         * a phys_disk entry and a more detailed disk_data entry.
         */
-       fstat(fd, &stb);
+       if (fstat(fd, &stb) != 0)
+               return 1;
        n = find_unused_pde(ddf);
        if (n == DDF_NOTFOUND) {
                pr_err("No free slot in array, cannot add disk\n");
index 2b8b6fda976c57688a9d88caa06df8e2b0ed0e51..4d2573711a9e0f6fabfba07777cc581c38850385 100644 (file)
@@ -4239,7 +4239,10 @@ load_imsm_disk(int fd, struct intel_super *super, char *devname, int keep_fd)
 
        dl = xcalloc(1, sizeof(*dl));
 
-       fstat(fd, &stb);
+       if (fstat(fd, &stb) != 0) {
+               free(dl);
+               return 1;
+       }
        dl->major = major(stb.st_rdev);
        dl->minor = minor(stb.st_rdev);
        dl->next = super->disks;
@@ -5981,7 +5984,8 @@ static int add_to_super_imsm(struct supertype *st, mdu_disk_info_t *dk,
        if (super->current_vol >= 0)
                return add_to_super_imsm_volume(st, dk, fd, devname);
 
-       fstat(fd, &stb);
+       if (fstat(fd, &stb) != 0)
+               return 1;
        dd = xcalloc(sizeof(*dd), 1);
        dd->major = major(stb.st_rdev);
        dd->minor = minor(stb.st_rdev);