#1144405 msr-tools: rdmsr and wrmsr segfault when invoked with -a without the msr module loaded

Package:
msr-tools
Source:
msr-tools
Description:
Utilities for modifying MSRs from userspace
Submitter:
Leah Tian Goldberg
Date:
2026-08-14 16:27:02 UTC
Severity:
normal
#1144405#5
Date:
2026-08-14 16:24:46 UTC
From:
To:
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);
    }