Skip to content

Commit b701eaf

Browse files
[no-relnote] Add e2e test for firmware path traversal
A container image could be crafted with a symbolic link in /lib/firmware/nvidia/ that points to a location outside of the container's root filesystem. When running such a container with the NVIDIA Container Toolkit, this could potentially lead to files being created on the host filesystem. This change adds an end-to-end test to ensure that the toolkit is not vulnerable to this kind of path traversal attack. Signed-off-by: Carlos Eduardo Arango Gutierrez <[email protected]>
1 parent d6326e7 commit b701eaf

File tree

2 files changed

+55
-1
lines changed

2 files changed

+55
-1
lines changed

tests/e2e/nvidia-container-toolkit_test.go

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ package e2e
1818

1919
import (
2020
"context"
21+
"fmt"
2122
"path/filepath"
2223
"strings"
2324

@@ -297,4 +298,57 @@ var _ = Describe("docker", Ordered, ContinueOnFailure, func() {
297298
Expect(err).ToNot(HaveOccurred())
298299
})
299300
})
301+
302+
When("Running a container where the firmware folder resolves outside the container root", Ordered, func() {
303+
var outputDir string
304+
BeforeAll(func(ctx context.Context) {
305+
output, _, err := runner.Run("mktemp -d -p $(pwd)")
306+
Expect(err).ToNot(HaveOccurred())
307+
outputDir = strings.TrimSpace(output)
308+
309+
_, _, err = runner.Run("docker pull ubuntu")
310+
Expect(err).ToNot(HaveOccurred())
311+
312+
_, _, err = runner.Run(`docker build -t firmware-test \
313+
--build-arg RM_VERSION="$(basename $(ls -d /lib/firmware/nvidia/*.*))" \
314+
--build-arg CURRENT_DIR="` + outputDir + `" \
315+
- <<EOF
316+
FROM ubuntu
317+
RUN mkdir -p /lib/firmware/nvidia/
318+
ARG RM_VERSION
319+
ARG CURRENT_DIR
320+
RUN ln -s /../../../../../../../../\$CURRENT_DIR /lib/firmware/nvidia/\$RM_VERSION
321+
EOF`)
322+
Expect(err).ToNot(HaveOccurred())
323+
})
324+
325+
AfterEach(func(ctx context.Context) {
326+
output, _, err := runner.Run("ls -A " + outputDir)
327+
Expect(err).ToNot(HaveOccurred())
328+
Expect(output).To(BeEmpty())
329+
})
330+
331+
AfterAll(func(ctx context.Context) {
332+
if outputDir != "" {
333+
runner.Run(fmt.Sprintf("rm -rf %s", outputDir))
334+
}
335+
})
336+
337+
It("should not fail when using CDI", func(ctx context.Context) {
338+
output, _, err := runner.Run("docker run --rm --runtime=nvidia -e NVIDIA_VISIBLE_DEVICES=runtime.nvidia.com/gpu=all firmware-test")
339+
Expect(err).ToNot(HaveOccurred())
340+
Expect(output).To(BeEmpty())
341+
})
342+
343+
It("should not fail when using the nvidia-container-runtime", func(ctx context.Context) {
344+
_, _, err := runner.Run("docker run --rm --runtime=nvidia -e NVIDIA_VISIBLE_DEVICES=all -e NVIDIA_DRIVER_CAPABILITIES=all firmware-test")
345+
Expect(err).ToNot(HaveOccurred())
346+
})
347+
348+
It("should fail when using the nvidia-container-runtime-hook", Label("legacy"), func(ctx context.Context) {
349+
_, stderr, err := runner.Run("docker run --rm --runtime=runc --gpus=all firmware-test")
350+
Expect(err).To(HaveOccurred())
351+
Expect(stderr).To(ContainSubstring("nvidia-container-cli.real: mount error: path error:"))
352+
})
353+
})
300354
})

tests/e2e/runner.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ func (r remoteRunner) Run(script string) (string, string, error) {
124124
// Run the script
125125
err = session.Run(script)
126126
if err != nil {
127-
return "", "", fmt.Errorf("script execution failed: %v\nSTDOUT: %s\nSTDERR: %s", err, stdout.String(), stderr.String())
127+
return "", stderr.String(), fmt.Errorf("script execution failed: %v\nSTDOUT: %s\nSTDERR: %s", err, stdout.String(), stderr.String())
128128
}
129129

130130
// Return stdout as string if no errors

0 commit comments

Comments
 (0)