]> git.ipfire.org Git - thirdparty/dracut.git/commitdiff
fix(skipcpio): improve error checking
authorShreenidhi Shedi <sshedi@vmware.com>
Sun, 8 Aug 2021 07:03:40 +0000 (12:33 +0530)
committerJóhann B. Guðmundsson <johannbg@gmail.com>
Fri, 27 Aug 2021 17:25:35 +0000 (17:25 +0000)
Some other minor tweaks

Signed-off-by: Shreenidhi Shedi <sshedi@vmware.com>
src/skipcpio/skipcpio.c

index fd9b4e46ad77ec63f7d4e6ce50993a31ac840774..89cc354915dec17bf9843667f7650289797bf784 100644 (file)
@@ -1,4 +1,4 @@
-/* dracut-install.c  -- install files and executables
+/* skipcpio.c
 
    Copyright (C) 2012 Harald Hoyer
    Copyright (C) 2012 Red Hat, Inc.  All rights reserved.
 #include <string.h>
 
 #define CPIO_MAGIC "070701"
+
 #define CPIO_END "TRAILER!!!"
 #define CPIO_ENDLEN (sizeof(CPIO_END) - 1)
 
 #define CPIO_ALIGNMENT 4
 
+#define ALIGN_UP(n, a) (((n) + (a) - 1) & (~((a) - 1)))
+
+#define pr_err(fmt, ...) \
+        fprintf(stderr, "ERROR: %s:%d:%s(): " fmt, __FILE__, __LINE__, \
+                __func__, ##__VA_ARGS__)
+
 struct cpio_header {
         char c_magic[6];
         char c_ino[8];
@@ -62,110 +69,135 @@ union buf_union {
 
 static union buf_union buf;
 
-#define ALIGN_UP(n, a) (((n) + (a) - 1) & (~((a) - 1)))
-
 int main(int argc, char **argv)
 {
-        FILE *f;
         size_t s;
+        long pos = 0;
+        FILE *f = NULL;
+        char *fname = NULL;
+        int ret = EXIT_FAILURE;
+        unsigned long filesize;
+        unsigned long filename_length;
 
         if (argc != 2) {
                 fprintf(stderr, "Usage: %s <file>\n", argv[0]);
-                exit(1);
+                goto end;
         }
 
-        f = fopen(argv[1], "r");
-
+        fname = argv[1];
+        f = fopen(fname, "r");
         if (f == NULL) {
-                fprintf(stderr, "Cannot open file '%s'\n", argv[1]);
-                exit(1);
+                pr_err("Cannot open file '%s'\n", fname);
+                goto end;
         }
 
-        s = fread(&buf.cpio, sizeof(buf.cpio), 1, f);
-        if (s <= 0) {
-                fprintf(stderr, "Read error from file '%s'\n", argv[1]);
-                fclose(f);
-                exit(1);
+        if ((fread(&buf.cpio, sizeof(buf.cpio), 1, f) != 1) ||
+            ferror(f)) {
+                pr_err("Read error from file '%s'\n", fname);
+                goto end;
         }
-        fseek(f, 0, SEEK_SET);
-
-        /* check, if this is a cpio archive */
-        if (memcmp(buf.cpio.h.c_magic, CPIO_MAGIC, 6) == 0) {
 
-                long pos = 0;
+        if (fseek(f, 0, SEEK_SET)) {
+                pr_err("fseek error on file '%s'\n", fname);
+                goto end;
+        }
 
-                unsigned long filesize;
-                unsigned long filename_length;
+        /* check, if this is a cpio archive */
+        if (memcmp(buf.cpio.h.c_magic, CPIO_MAGIC, 6)) {
+                goto cat_rest;
+        }
 
-                do {
-                        // zero string, spilling into next unused field, to use strtol
-                        buf.cpio.h.c_chksum[0] = 0;
-                        filename_length = strtoul(buf.cpio.h.c_namesize, NULL, 16);
-                        pos = ALIGN_UP(pos + sizeof(struct cpio_header) + filename_length, CPIO_ALIGNMENT);
-
-                        // zero string, spilling into next unused field, to use strtol
-                        buf.cpio.h.c_dev_maj[0] = 0;
-                        filesize = strtoul(buf.cpio.h.c_filesize, NULL, 16);
-                        pos = ALIGN_UP(pos + filesize, CPIO_ALIGNMENT);
-
-                        if (filename_length == (CPIO_ENDLEN + 1)
-                            && strncmp(buf.cpio.filename, CPIO_END, CPIO_ENDLEN) == 0) {
-                                fseek(f, pos, SEEK_SET);
-                                break;
+        do {
+                // zero string, spilling into next unused field, to use strtol
+                buf.cpio.h.c_chksum[0] = 0;
+                filename_length = strtoul(buf.cpio.h.c_namesize, NULL, 16);
+                pos = ALIGN_UP(pos + sizeof(struct cpio_header) + filename_length, CPIO_ALIGNMENT);
+
+                // zero string, spilling into next unused field, to use strtol
+                buf.cpio.h.c_dev_maj[0] = 0;
+                filesize = strtoul(buf.cpio.h.c_filesize, NULL, 16);
+                pos = ALIGN_UP(pos + filesize, CPIO_ALIGNMENT);
+
+                if (filename_length == (CPIO_ENDLEN + 1)
+                    && strncmp(buf.cpio.filename, CPIO_END, CPIO_ENDLEN) == 0) {
+                        if (fseek(f, pos, SEEK_SET)) {
+                                pr_err("fseek\n");
+                                goto end;
                         }
+                        break;
+                }
 
-                        if (fseek(f, pos, SEEK_SET) != 0) {
-                                perror("fseek");
-                                exit(1);
-                        }
+                if (fseek(f, pos, SEEK_SET)) {
+                        pr_err("fseek\n");
+                        goto end;
+                }
 
-                        if (fread(&buf.cpio, sizeof(buf.cpio), 1, f) != 1) {
-                                perror("fread");
-                                exit(1);
-                        }
+                if ((fread(&buf.cpio, sizeof(buf.cpio), 1, f) != 1) ||
+                    ferror(f)) {
+                        pr_err("fread\n");
+                        goto end;
+                }
 
-                        if (memcmp(buf.cpio.h.c_magic, CPIO_MAGIC, 6) != 0) {
-                                fprintf(stderr, "Corrupt CPIO archive!\n");
-                                exit(1);
-                        }
-                } while (!feof(f));
+                if (memcmp(buf.cpio.h.c_magic, CPIO_MAGIC, 6)) {
+                        pr_err("Corrupt CPIO archive!\n");
+                        goto end;
+                }
+        } while (!feof(f));
 
-                if (feof(f)) {
-                        /* CPIO_END not found, just cat the whole file */
-                        fseek(f, 0, SEEK_SET);
-                } else {
-                        /* skip zeros */
-                        do {
-                                size_t i;
+        if (feof(f)) {
+                /* CPIO_END not found, just cat the whole file */
+                if (fseek(f, 0, SEEK_SET)) {
+                        pr_err("fseek\n");
+                        goto end;
+                }
+        } else {
+                /* skip zeros */
+                do {
+                        size_t i;
 
-                                s = fread(buf.copy_buffer, 1, sizeof(buf.copy_buffer) - 1, f);
-                                if (s <= 0)
-                                        break;
+                        s = fread(buf.copy_buffer, 1, sizeof(buf.copy_buffer) - 1, f);
+                        if (ferror(f)) {
+                                pr_err("fread\n");
+                                goto end;
+                        }
 
-                                for (i = 0; (i < s) && (buf.copy_buffer[i] == 0); i++) ;
+                        for (i = 0; (i < s) && (buf.copy_buffer[i] == 0); i++) ;
 
-                                if (buf.copy_buffer[i] != 0) {
-                                        pos += i;
+                        if (buf.copy_buffer[i]) {
+                                pos += i;
 
-                                        fseek(f, pos, SEEK_SET);
-                                        break;
+                                if (fseek(f, pos, SEEK_SET)) {
+                                        pr_err("fseek\n");
+                                        goto end;
                                 }
+                                break;
+                        }
 
-                                pos += s;
-                        } while (!feof(f));
-                }
+                        pos += s;
+                } while (!feof(f));
         }
+
+cat_rest:
         /* cat out the rest */
         while (!feof(f)) {
                 s = fread(buf.copy_buffer, 1, sizeof(buf.copy_buffer), f);
-                if (s <= 0)
-                        break;
+                if (ferror(f)) {
+                        pr_err("fread\n");
+                        goto end;
+                }
 
-                s = fwrite(buf.copy_buffer, 1, s, stdout);
-                if (s <= 0)
-                        break;
+                if (fwrite(buf.copy_buffer, 1, s, stdout) != s) {
+                        pr_err("fwrite\n");
+                        goto end;
+                }
+        }
+
+        ret = EXIT_SUCCESS;
+
+end:
+        if (f) {
+                fclose(f);
         }
-        fclose(f);
 
-        return EXIT_SUCCESS;
+        return ret;
 }