From c149b054fe5b1851860fd01d54596ea75f5008d3 Mon Sep 17 00:00:00 2001 From: Sandipan Das Date: Wed, 13 Apr 2022 11:45:08 +0530 Subject: [PATCH 09/15] x86: Fix clock frequency parsing AMD processors do not advertise a base clock frequency as a part of the "model name" in /proc/cpuinfo. The parsing must fail in order to let os_calibrate() determine clock speed from cpufreq information or from TSC instead. Since the parser fails to find "@", strcspn() returns the length of the line instead and sscanf() ends up scanning garbage values beyond the null terminator that match the format specifier. To avoid this, add an additional check that makes the condition fail if "@" is not found. Fixes: eaeed92 ("Powerpc: Fix CPU% utilization for PowerVMs") Signed-off-by: Sandipan Das --- x86/util.c | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/x86/util.c b/x86/util.c index fdff877..655a677 100644 --- a/x86/util.c +++ b/x86/util.c @@ -67,27 +67,36 @@ rdtsc(void) /* * Check the cpu name in proc info. Intel CPUs always have @ x.y - * Ghz and that is the TSC frequency. + * GHz and that is the TSC frequency. AMD CPUs do not advertise + * clock frequency as a part of the model name. */ int arch__cpuinfo_freq(double *freq, char *unit) { FILE *f; char *line = NULL; - size_t len = 0; + size_t idx, len = 0; int ret = -1; if ((f = fopen(CPUINFO_PATH, "r")) == NULL) { return (-1); } - while (getline(&line, &len, f) > 0) { + while ((len = getline(&line, &len, f)) > 0) { if (strncmp(line, "model name", sizeof ("model name") - 1) != 0) { continue; } - if (sscanf(line + strcspn(line, "@") + 1, "%lf%10s", - freq, unit) == 2) { + idx = strcspn(line, "@") + 1; + + /* + * The model name will not change for other processors. So + * bail out if "@" is not found. + */ + if (idx >= len) + break; + + if (sscanf(line + idx, "%lf%10s", freq, unit) == 2) { if (strcasecmp(unit, "GHz") == 0) { *freq *= GHZ; } else if (strcasecmp(unit, "Mhz") == 0) { -- 2.31.1