summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSamuel Holland <samuel@sholland.org>2020-03-28 20:58:34 -0500
committerSamuel Holland <samuel@sholland.org>2020-03-28 21:02:02 -0500
commit585d0700c7dbbc3cf032ad2e710d48eda85dd7ce (patch)
tree16f1d3922cc64132bd9d1b2bf95507265841273d
parent3374e1605d718816d08ba91721aa82ec73086b9d (diff)
avoid out-of-bounds read after invalid %cpu conversion
In the case where no CPU number is given, skipping a character of padding actually skips the null terminator, causing further iterations through the loop to read out of bounds. Have sscanf() return the number of characters read, instead of reconstructing it from the CPU number. This was observed as a failure in test 024-cpu-usage-invalid-cpu.
-rw-r--r--src/print_cpu_usage.c11
1 files changed, 3 insertions, 8 deletions
diff --git a/src/print_cpu_usage.c b/src/print_cpu_usage.c
index 979e082..abf3481 100644
--- a/src/print_cpu_usage.c
+++ b/src/print_cpu_usage.c
@@ -183,7 +183,8 @@ void print_cpu_usage(yajl_gen json_gen, char *buffer, const char *format, const
#if defined(__linux__)
else if (BEGINS_WITH(walk + 1, "cpu")) {
int number = -1;
- sscanf(walk + 1, "cpu%d", &number);
+ int length = strlen("cpu");
+ sscanf(walk + 1, "cpu%d%n", &number, &length);
if (number == -1) {
fprintf(stderr, "i3status: provided CPU number cannot be parsed\n");
} else if (number >= cpu_count) {
@@ -194,13 +195,7 @@ void print_cpu_usage(yajl_gen json_gen, char *buffer, const char *format, const
int cpu_diff_usage = (cpu_diff_total ? (1000 * (cpu_diff_total - cpu_diff_idle) / cpu_diff_total + 5) / 10 : 0);
outwalk += sprintf(outwalk, "%02d%s", cpu_diff_usage, pct_mark);
}
- int padding = 1;
- int step = 10;
- while (step <= number) {
- step *= 10;
- padding++;
- }
- walk += strlen("cpu") + padding;
+ walk += length;
}
#endif
else {