fix(security): classify DeepStream as GPU backend and enforce pixel limits (#50755)

Signed-off-by: jperezde <jperezde@redhat.com>

Juan Pérez de Algaba committed Aug 3, 2026 at 10:23 UTC d83eb0b36bfbe26fc856ffdb60f05c8bd460f2fd
3 files changed +35
tests/multimodal/media/test_video.py
+28
@@ -470,3 +470,31 @@ class TestMergeKwargsGpuBackendPolicy:
470 )
471 assert result.get("backend") != "pynvvideocodec"
472 assert result["video_backend"] == "pynvvideocodec"
473 +
474 + def test_deepstream_requires_gpu(self):
475 + assert VIDEO_LOADER_REGISTRY.backend_requires_gpu("deepstream")
476 +
477 + def test_strips_backend_deepstream_when_not_static(self):
478 + result = VideoMediaIO.merge_kwargs(
479 + default_kwargs=None,
480 + runtime_kwargs={"backend": "deepstream"},
481 + )
482 + assert result.get("backend") != "deepstream"
483 +
484 + def test_preserves_backend_deepstream_when_static(self):
485 + result = VideoMediaIO.merge_kwargs(
486 + default_kwargs={"backend": "deepstream"},
487 + runtime_kwargs={"backend": "deepstream", "num_frames": 8},
488 + )
489 + assert result["backend"] == "deepstream"
490 + assert result["num_frames"] == 8
491 +
492 + def test_strips_pool_size_from_runtime(self):
493 + result = VideoMediaIO.merge_kwargs(
494 + default_kwargs={"backend": "deepstream"},
495 + runtime_kwargs={"backend": "deepstream", "pool_size": 4},
496 + )
497 + assert "pool_size" not in result
498 +
499 + def test_unknown_backend_not_treated_as_gpu(self):
500 + assert not VIDEO_LOADER_REGISTRY.backend_requires_gpu("totally_unknown")
vllm/multimodal/media/video.py
+1
@@ -35,6 +35,7 @@ class VideoMediaIO(MediaIO[MediaWithBytes[tuple[npt.NDArray, dict[str, Any]]]]):
35 # Decoder GPU memory is reserved from the startup value.
36 runtime_kwargs = dict(runtime_kwargs)
37 runtime_kwargs.pop("hw_decoders", None)
38 + runtime_kwargs.pop("pool_size", None)
39
40 # Block request-level selection of GPU video backends that
41 # were not configured (and VRAM-reserved) at startup.
vllm/multimodal/video.py
+6
@@ -92,6 +92,10 @@ class VideoLoaderRegistry(ExtensionManager):
92
93 return self.processor2backend.get(video_processor)
94
95 + def register_gpu_codec(self, name: str) -> None:
96 + """Mark a codec name as requiring GPU without registering a loader."""
97 + self._requires_gpu[name] = True
98 +
99 def backend_requires_gpu(self, name: str) -> bool:
100 return self._requires_gpu.get(name, False)
101
@@ -208,6 +212,7 @@ class VideoLoader:
212
213
214 VIDEO_LOADER_REGISTRY = VideoLoaderRegistry()
215 +VIDEO_LOADER_REGISTRY.register_gpu_codec("deepstream")
216
217 PYNVVIDEOCODEC_VIDEO_BACKEND: Literal["pynvvideocodec"] = "pynvvideocodec"
218 # Per-decoder upper bound reserved for persistent PyNvVideoCodec surfaces.
@@ -1136,6 +1141,7 @@ class VideoBackend(
1141 from nvidia.deepstream_videodecode import probe_metadata
1142
1143 total_frames, original_fps, duration, _w, _h, codec = probe_metadata(data)
1144 + _check_frame_pixel_limit(_w, _h)
1145 source = cls._prepare_source(
1146 VideoSourceMetadata(
1147 total_frames_num=total_frames,