]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
tools/x86/kcpuid: Fix error handling
authorAhmed S. Darwish <darwi@linutronix.de>
Mon, 24 Mar 2025 14:20:22 +0000 (15:20 +0100)
committerIngo Molnar <mingo@kernel.org>
Tue, 25 Mar 2025 08:53:43 +0000 (09:53 +0100)
Error handling in kcpuid is unreliable.  On malloc() failures, the code
prints an error then just goes on.  The error messages are also printed
to standard output instead of standard error.

Use err() and errx() from <err.h> to direct all error messages to
standard error and automatically exit the program.  Use err() to include
the errno information, and errx() otherwise.  Use warnx() for warnings.

While at it, alphabetically reorder the header includes.

[ mingo: Fix capitalization in the help text while at it. ]

Fixes: c6b2f240bf8d ("tools/x86: Add a kcpuid tool to show raw CPU features")
Reported-by: Remington Brasga <rbrasga@uci.edu>
Signed-off-by: Ahmed S. Darwish <darwi@linutronix.de>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Cc: H. Peter Anvin <hpa@zytor.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Josh Poimboeuf <jpoimboe@redhat.com>
Link: https://lore.kernel.org/r/20250324142042.29010-2-darwi@linutronix.de
Closes: https://lkml.kernel.org/r/20240926223557.2048-1-rbrasga@uci.edu
tools/arch/x86/kcpuid/kcpuid.c

index 1b25c0a95d3f9adc61ee32517c65ff486bf3140a..40a9e59c2fd568c9dc2b85d24a20696bda99aed2 100644 (file)
@@ -1,11 +1,12 @@
 // SPDX-License-Identifier: GPL-2.0
 #define _GNU_SOURCE
 
-#include <stdio.h>
+#include <err.h>
+#include <getopt.h>
 #include <stdbool.h>
+#include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
-#include <getopt.h>
 
 #define ARRAY_SIZE(x)  (sizeof(x) / sizeof((x)[0]))
 #define min(a, b)      (((a) < (b)) ? (a) : (b))
@@ -145,14 +146,14 @@ static bool cpuid_store(struct cpuid_range *range, u32 f, int subleaf,
        if (!func->leafs) {
                func->leafs = malloc(sizeof(struct subleaf));
                if (!func->leafs)
-                       perror("malloc func leaf");
+                       err(EXIT_FAILURE, NULL);
 
                func->nr = 1;
        } else {
                s = func->nr;
                func->leafs = realloc(func->leafs, (s + 1) * sizeof(*leaf));
                if (!func->leafs)
-                       perror("realloc f->leafs");
+                       err(EXIT_FAILURE, NULL);
 
                func->nr++;
        }
@@ -211,7 +212,7 @@ struct cpuid_range *setup_cpuid_range(u32 input_eax)
 
        range = malloc(sizeof(struct cpuid_range));
        if (!range)
-               perror("malloc range");
+               err(EXIT_FAILURE, NULL);
 
        if (input_eax & 0x80000000)
                range->is_ext = true;
@@ -220,7 +221,7 @@ struct cpuid_range *setup_cpuid_range(u32 input_eax)
 
        range->funcs = malloc(sizeof(struct cpuid_func) * idx_func);
        if (!range->funcs)
-               perror("malloc range->funcs");
+               err(EXIT_FAILURE, NULL);
 
        range->nr = idx_func;
        memset(range->funcs, 0, sizeof(struct cpuid_func) * idx_func);
@@ -395,8 +396,8 @@ static int parse_line(char *line)
        return 0;
 
 err_exit:
-       printf("Warning: wrong line format:\n");
-       printf("\tline[%d]: %s\n", flines, line);
+       warnx("Wrong line format:\n"
+             "\tline[%d]: %s", flines, line);
        return -1;
 }
 
@@ -418,10 +419,8 @@ static void parse_text(void)
                file = fopen("./cpuid.csv", "r");
        }
 
-       if (!file) {
-               printf("Fail to open '%s'\n", filename);
-               return;
-       }
+       if (!file)
+               err(EXIT_FAILURE, "%s", filename);
 
        while (1) {
                ret = getline(&line, &len, file);
@@ -530,7 +529,7 @@ static inline struct cpuid_func *index_to_func(u32 index)
        func_idx = index & 0xffff;
 
        if ((func_idx + 1) > (u32)range->nr) {
-               printf("ERR: invalid input index (0x%x)\n", index);
+               warnx("Invalid input index (0x%x)", index);
                return NULL;
        }
        return &range->funcs[func_idx];
@@ -562,7 +561,7 @@ static void show_info(void)
                                return;
                        }
 
-                       printf("ERR: invalid input subleaf (0x%x)\n", user_sub);
+                       warnx("Invalid input subleaf (0x%x)", user_sub);
                }
 
                show_func(func);
@@ -593,15 +592,15 @@ static void setup_platform_cpuid(void)
 
 static void usage(void)
 {
-       printf("kcpuid [-abdfhr] [-l leaf] [-s subleaf]\n"
-               "\t-a|--all             Show both bit flags and complex bit fields info\n"
-               "\t-b|--bitflags        Show boolean flags only\n"
-               "\t-d|--detail          Show details of the flag/fields (default)\n"
-               "\t-f|--flags           Specify the cpuid csv file\n"
-               "\t-h|--help            Show usage info\n"
-               "\t-l|--leaf=index      Specify the leaf you want to check\n"
-               "\t-r|--raw             Show raw cpuid data\n"
-               "\t-s|--subleaf=sub     Specify the subleaf you want to check\n"
+       warnx("kcpuid [-abdfhr] [-l leaf] [-s subleaf]\n"
+             "\t-a|--all             Show both bit flags and complex bit fields info\n"
+             "\t-b|--bitflags        Show boolean flags only\n"
+             "\t-d|--detail          Show details of the flag/fields (default)\n"
+             "\t-f|--flags           Specify the CPUID CSV file\n"
+             "\t-h|--help            Show usage info\n"
+             "\t-l|--leaf=index      Specify the leaf you want to check\n"
+             "\t-r|--raw             Show raw CPUID data\n"
+             "\t-s|--subleaf=sub     Specify the subleaf you want to check"
        );
 }
 
@@ -652,7 +651,7 @@ static int parse_options(int argc, char *argv[])
                        user_sub = strtoul(optarg, NULL, 0);
                        break;
                default:
-                       printf("%s: Invalid option '%c'\n", argv[0], optopt);
+                       warnx("Invalid option '%c'", optopt);
                        return -1;
        }