![]() |
|
Message-ID: <7555c072-80b4-4703-94a2-b5239aaabbf8@suse.de>
Date: Thu, 27 Mar 2025 10:11:04 +0100
From: Wolfgang Frisch <wfrisch@...e.de>
To: oss-security@...ts.openwall.com
Subject: wait3() system call as a side-channel in setuid programs
(nvidia-modprobe CVE-2024-0149)
Hello oss-sec,
this report details an information disclosure vulnerability in
nvidia-modprobe [1]. While the immediate impact of the bug itself is
limited, it highlights one of the many pitfalls to be aware of when
writing or reviewing setuid programs. You can also find a rendered
version of this report on our blog [2].
1) Introduction
===============
nvidia-modprobe is a setuid-root helper utility for the proprietary
Nvidia GPU display driver that loads kernel modules and creates
character devices required for userspace GPU access. Normally, drivers
do this via udev. However, kernel licensing restrictions prohibit
Nvidia's proprietary kernel module from generating uevents, which are
required for udev to work. Therefore this special helper is needed.
We reviewed nvidia-modprobe as part of our whitelisting process, which
requires an audit for all newly introduced setuid binaries in openSUSE.
The version we reviewed was 550.127.05 [3] and this report is based on
that version. Upstream released a bugfix in version 550.144.03 [4] and
a security advisory [5].
2) `wait3()` as a Side Channel in Setuid Programs
=================================================
The `wait3()` system call allows the calling process to obtain status
information for child processes, similar to `waitpid()`. Unlike
`waitpid()`, `wait3()` also returns resource usage information. The
measurements returned by this call include CPU time, memory consumption
and lower-level information such as the number of minor and major page
faults that occurred during the child's runtime. See also
`man 2 getrusage` [6].
Perhaps surprisingly, `wait3()` also works for setuid sub-processes,
leaking quite a bit of information about the behavior of the target
program, which is running with elevated privileges.
A convenient way to try this out is GNU Time [7], a small utility that
spawns a target process and prints the output of `wait3()`, for example:
```sh
/usr/bin/time -v nvidia-modprobe
```
3) File Existence Test (CVE-2024-0149)
======================================
In the case of nvidia-modprobe, we can leverage `wait3()` for a file
existence test.
When executed with the option `-f NVIDIA-CAPABILITY-DEVICE-FILE` (an
arbitrary path), nvidia-modprobe performs the following steps:
- attempt to open the supplied path as root
- if the path does exist:
- read one or more lines
- parse each line (implemented safely)
- exit silently, return code 0
- if the path does not exist:
- exit silently, return code 0
It turns out that reading the first line of the supplied path sometimes
causes a minor page fault. The number of page faults is not perfectly
constant across multiple executions, depending on whether the page
mapped by the kernel is dirty or not. However, if the file does not
exist, it cannot be read, and therefore no page faults will be
triggered. We can execute nvidia-modprobe repeatedly, calculate the
median number of page faults, and infer whether the supplied path exists
or not, even if the caller does not have the necessary file system
permissions.
Simplified example:
```
$ /usr/bin/time -q --format=%R nvidia-modprobe -f /root/.bash_history
80
$ /usr/bin/time -q --format=%R nvidia-modprobe -f /root/does/not/exist
79
```
The output fluctuates, but it only takes a few repetitions to get a
reliable signal from the median.
4) Bugfix
=========
Upstream published a bugfix [8]. This commit limits the queried path to
files below `/proc/driver/nvidia` before attempting to read from it,
eliminating the information leak.
5) CVE Assignment
=================
Upstream assigned CVE-2024-0149 for this issue.
6) Other Packages
=================
Considering the relatively obscure nature of this side channel attack,
we decided to briefly look into a couple of other packages exhibiting
similar usage patterns:
- `shadow`
- `chsh`: negative
- `util-linux`
- `mount -T`: negative
- `umount`: negative
Even though we did not find additional instances of this problem, and
the severity of this vulnerability is rather low, it's still one of many
pitfalls to keep in mind when writing or auditing setuid programs.
7) Timeline
===========
2024-10-02: We noticed the issue and started tracking it privately in [9].
2024-10-09: We shared the information with NVIDIA PSIRT via email,
offering coordinated disclosure.
2024-10-12: We received an initial confirmation from Nvidia.
2024-10-22: We agreed on 2025-01-16 as the Coordinated Release Date.
2025-01-16: CVE-2024-0149 was assigned by Nvidia.
2025-01-16: Nvidia released the fix as part of version 550.144.03 [4]
8) References
=============
[1]: https://github.com/NVIDIA/nvidia-modprobe
[2]: https://security.opensuse.org/2025/03/26/nvidia-modprobe.html
[3]: https://github.com/NVIDIA/nvidia-modprobe/releases/tag/550.127.05
[4]: https://github.com/NVIDIA/nvidia-modprobe/releases/tag/550.144.03
[5]:
https://nvidia.custhelp.com/app/answers/detail/a_id/5614/~/security-bulletin%3A-nvidia-gpu-display-driver---january-2025
[6]: https://manpages.opensuse.org/Tumbleweed/man-pages/getrusage.2.en.html
[7]: https://www.gnu.org/software/time/
[8]:
https://github.com/NVIDIA/nvidia-modprobe/commit/83b777c5fbbcdfd48004b0b099cf0a8a9ee9359f
[9]: https://bugzilla.opensuse.org/show_bug.cgi?id=1231257
All the best,
Wolfgang
--
Wolfgang Frisch <wolfgang.frisch@...e.com>
Security Engineer
OpenPGP fingerprint: A2E6 B7D4 53E9 544F BC13 D26B D9B3 56BD 4D4A 2D15
SUSE Software Solutions Germany GmbH, Frankenstraße 146, 90461 Nürnberg
Download attachment "OpenPGP_signature.asc" of type "application/pgp-signature" (841 bytes)
Powered by blists - more mailing lists
Please check out the Open Source Software Security Wiki, which is counterpart to this mailing list.
Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.