Fedora Account System
Red Hat Associate
Red Hat Customer
Please see https://github.com/fedora-selinux/selinux-policy/pull/3087 The NVIDIA driver uses filp_open() to create an anonymous temporary file during system suspend, which it uses to temporarily store the contents of GPU video memory when video memory preservation is enabled. This anonymous file is created in the filesystem backing /tmp by default, but the path can be configured with the NVreg_TemporaryFilePath= kernel module parameter. A future version of the driver is planned to switch to using an anonymous shmem (tmpfs) file by default instead. Currently, the code to do this is triggered by a write to /proc/driver/nvidia/suspend, which comes from the nvidia-sleep.sh script that is run by the nvidia-suspend.service systemd unit. This service runs in unconfined_service_t. A future version of the NVIDIA driver will instead run this code in response to systemd-sleep's write to /sys/power/state, which runs in the very restrictive systemd_sleep_t context, which blocks this filesystem access, causing suspend to fail. Reproducible: Always Steps to Reproduce: 1. Install the NVIDIA 615 release (once available), or an earlier release with NVreg_UseKernelSuspendNotifiers=1 enabled and this patch applied: https://github.com/NVIDIA/open-gpu-kernel-modules/compare/main...aaronp24:open-gpu-kernel-modules:suspend-resume-shmem-file 2. Enter S3 or S2idle suspend Actual Results: SELinux blocks the driver's ability to use shmem_file_setup(), which causes suspend to fail. Expected Results: shmem_file_setup() and the subsequent write and read operations should succeed, allowing the driver to temporarily store VRAM contents that will be lost during suspend.
Hello, I appreciate the proactive approach. The correct way though would be to confine the service and use a private tmpfs file. Is the service provided in any fedora package?
The issue here is that we're actually moving *away* from a separate unconfined service and instead running in the kernel in response to a write to /sys/power/state from systemd-sleep, which runs in the systemd_sleep_t context. The kernel stack inherits the security context from the process doing the write so our kernel-side calls fail without this. Users can turn this new behavior off by setting NVreg_UseKernelSuspendNotifiers=0 and then this path runs in response to a write to /proc/driver/nvidia/suspend from a script that runs from the nvidia-suspend.service systemd unit. We can talk about constraining that service but I think that should be a separate bug. Does that sound reasonable?
Thank for clarification, bu I am still a bit confused. The PR only adds fs_rw_tmpfs_files(systemd_sleep_t) which expands to fs_rw_tmpfs_files(systemd_sleep_t) └── rw_files_pattern(systemd_sleep_t, tmpfs_t, tmpfs_t) ├── allow systemd_sleep_t tmpfs_t:dir search_dir_perms; │ ↳ search_dir_perms -> { getattr search open } └── allow systemd_sleep_t tmpfs_t:file rw_file_perms; ↳ rw_file_perms -> { open rw_inherited_file_perms } ↳ rw_inherited_file_perms -> { getattr read write append ioctl lock } tmpfs_t is assigned to /dev/shm, /run/shm, /usr/lib/udev/devices/shm On the other hand: # ls -lZ /sys/power/state -rw-r--r--. 1 root root system_u:object_r:sysfs_t:s0 4096 12. aug 15.15 /sys/power/state Which file sd-sleep wants to write to and which service created it? 6 systemd domains use their private tmpfs files.
The github pull request links to the driver change that will be in the next release: https://github.com/NVIDIA/open-gpu-kernel-modules/compare/main...aaronp24:open-gpu-kernel-modules:suspend-resume-shmem-file Existing drivers use filp_open() to open an anonymous file in some directory. It defaults to /tmp but it can be configured by setting the NVreg_TemporaryFilePath= module parameter. Future drivers that have the change I linked above will default to using shmem_file_setup() instead. That creates a completely anonymous file that's not backed by any real filesystem path, accessible to the kernel only. This anonymous shmem file is the one that gets tmpfs_t. The creation of this temporary, anonymous, kernel-only file is triggered by systemd-suspend.service, when it runs "/usr/lib/systemd/systemd-sleep suspend" and that opens and writes to /sys/power/state. On the kernel side, the write to that sysfs file triggers a call to pm_notifier_call_chain_robust(PM_SUSPEND_PREPARE, ...) that eventually calls this driver code.
Is this temporary file only going to be used within kernel space? If yes, then the driver should instead open it via shmem_kernel_file_setup(), which will mark the inode with S_PRIVATE, making it bypass security module checks (as is the norm for purely kernel-private files).
Hi Ondrej, Yes, the file is only used within kernel space and then only during the suspend / resume cycle. The file is closed as soon as resume is complete. I did look at shmem_kernel_file_setup() when I was working on the initial version of the change, but reviewers objected to using it to bypass LSM checks because the documentation mentions specifically that bypassing LSM is not its intended use: "There will be NO LSM permission checks against the underlying inode. So users of this interface must do LSM checks at a higher layer."
This bug appears to have been reported against 'rawhide' during the Fedora Linux 45 development cycle. Changing version to 45.
I managed to work around this in the driver, so I think this can be closed. I'm not sure the change is going to make it into the next release though, so this may be broken until a driver with the workaround can be released.