From cc790454f5c9c33d8a8fcbaa1c19e230aeb014b8 Mon Sep 17 00:00:00 2001 From: Nitish Date: Sun, 9 Aug 2026 01:52:05 +0530 Subject: [PATCH] fix(vGPUmonitor): clamp corrupt device count from shared memory region DeviceNum() returned int(sr.num) unclamped even though num is read from an mmap'd shared-memory cache written by the contained libvgpu. A torn or corrupt value larger than maxDevices makes metrics.go iterate out of bounds over the fixed-size [16] device arrays, and SetDeviceSmLimit/ SetDeviceMemoryLimit write OOB, panicking the vGPUmonitor daemonset pod. Clamp DeviceNum() to [0, maxDevices], mirroring the existing activeProcs() hardening, and make the limit setters iterate DeviceNum(). Signed-off-by: Nitish --- pkg/monitor/nvidia/v0/spec.go | 10 +++------- pkg/monitor/nvidia/v1/spec.go | 10 +++------- 2 files changed, 6 insertions(+), 14 deletions(-) diff --git a/pkg/monitor/nvidia/v0/spec.go b/pkg/monitor/nvidia/v0/spec.go index 444bddf827..fd9eaad4a2 100644 --- a/pkg/monitor/nvidia/v0/spec.go +++ b/pkg/monitor/nvidia/v0/spec.go @@ -78,7 +78,7 @@ func (s Spec) DeviceMax() int { } func (s Spec) DeviceNum() int { - return int(s.sr.num) + return int(min(max(s.sr.num, 0), uint64(maxDevices))) } // activeProcs returns the process slots currently in use. procnum is read from @@ -138,10 +138,8 @@ func (s Spec) DeviceSmUtil(idx int) uint64 { } func (s Spec) SetDeviceSmLimit(l uint64) { - idx := uint64(0) - for idx < s.sr.num { + for idx := 0; idx < s.DeviceNum(); idx++ { s.sr.smLimit[idx] = l - idx += 1 } } @@ -158,10 +156,8 @@ func (s Spec) DeviceMemoryLimit(idx int) uint64 { } func (s Spec) SetDeviceMemoryLimit(l uint64) { - idx := uint64(0) - for idx < s.sr.num { + for idx := 0; idx < s.DeviceNum(); idx++ { s.sr.limit[idx] = l - idx += 1 } } diff --git a/pkg/monitor/nvidia/v1/spec.go b/pkg/monitor/nvidia/v1/spec.go index 49a12aac11..dc1944de99 100644 --- a/pkg/monitor/nvidia/v1/spec.go +++ b/pkg/monitor/nvidia/v1/spec.go @@ -92,7 +92,7 @@ func (s Spec) DeviceMax() int { } func (s Spec) DeviceNum() int { - return int(s.sr.num) + return int(min(max(s.sr.num, 0), uint64(maxDevices))) } // activeProcs returns the process slots currently in use. procnum is read from @@ -152,10 +152,8 @@ func (s Spec) DeviceSmUtil(idx int) uint64 { } func (s Spec) SetDeviceSmLimit(l uint64) { - idx := uint64(0) - for idx < s.sr.num { + for idx := 0; idx < s.DeviceNum(); idx++ { s.sr.smLimit[idx] = l - idx += 1 } } @@ -172,10 +170,8 @@ func (s Spec) DeviceMemoryLimit(idx int) uint64 { } func (s Spec) SetDeviceMemoryLimit(l uint64) { - idx := uint64(0) - for idx < s.sr.num { + for idx := 0; idx < s.DeviceNum(); idx++ { s.sr.limit[idx] = l - idx += 1 } }