Dear Maintainer,
* What led up to the situation?
Running `rdmsr -a` or `wrmsr -a` to query or set MSR values
across all CPU cores when the `msr` kernel module is not
currently loaded into the kernel.
* What exactly did you do (or not do) that was effective (or ineffective)?
1. Unloaded the `msr` driver module so `/dev/cpu` is absent from the filesystem:
`sudo rmmod msr`
2. Executed `rdmsr` or `wrmsr` with the `-a` (all processors) flag:
`sudo rdmsr -a 0x10`
* What was the outcome of this action?
The utility crashed immediately with a
Segmentation Fault (`core dumped`).
In `rdmsr.c` (and `wrmsr.c`), the code calls `scandir("/dev/cpu", ...)`
to enumerate available CPUs. When the `msr` module is not loaded, `/dev/cpu`
does not exist and `scandir()` returns `-1`. Because the code lacks a check for
`dir_entries == -1`, it enters the `while (dir_entries--)` loop with a negative count,
leading to an invalid pointer dereference on `namelist[-2]`.
* What outcome did you expect instead?
The tool should check the return value of `scandir()`.
If `/dev/cpu` does not exist or cannot be scanned,
it should display an informative error message (e.g., instructing the user to load the
`msr` kernel module) and exit cleanly with an error status instead of crashing.
--- Proposed Fix ---
Adding error checking around the `scandir()` call in both `rdmsr.c` and `wrmsr.c`:
dir_entries = scandir("/dev/cpu", &namelist, dir_filter, 0);
if (dir_entries == -1) {
perror("rdmsr: scandir");
if (errno == ENOENT || errno == ENOTDIR)
fprintf(stderr, "rdmsr: may need to load msr module to populate /dev/cpu\n");
exit(1);
}