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.
This commit is contained in:
parent
3374e1605d
commit
585d0700c7
@ -183,7 +183,8 @@ void print_cpu_usage(yajl_gen json_gen, char *buffer, const char *format, const
|
|||||||
#if defined(__linux__)
|
#if defined(__linux__)
|
||||||
else if (BEGINS_WITH(walk + 1, "cpu")) {
|
else if (BEGINS_WITH(walk + 1, "cpu")) {
|
||||||
int number = -1;
|
int number = -1;
|
||||||
sscanf(walk + 1, "cpu%d", &number);
|
int length = strlen("cpu");
|
||||||
|
sscanf(walk + 1, "cpu%d%n", &number, &length);
|
||||||
if (number == -1) {
|
if (number == -1) {
|
||||||
fprintf(stderr, "i3status: provided CPU number cannot be parsed\n");
|
fprintf(stderr, "i3status: provided CPU number cannot be parsed\n");
|
||||||
} else if (number >= cpu_count) {
|
} 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);
|
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);
|
outwalk += sprintf(outwalk, "%02d%s", cpu_diff_usage, pct_mark);
|
||||||
}
|
}
|
||||||
int padding = 1;
|
walk += length;
|
||||||
int step = 10;
|
|
||||||
while (step <= number) {
|
|
||||||
step *= 10;
|
|
||||||
padding++;
|
|
||||||
}
|
|
||||||
walk += strlen("cpu") + padding;
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
else {
|
else {
|
||||||
|
Loading…
Reference in New Issue
Block a user