Skip to content

[UR] Misuse of std::vector reserve() causing undefined behavior in tests and examples #18032

@Maetveis

Description

@Maetveis

Describe the bug

UR tests and examples contain code patterns similar to the following:

std::uint32_t platformCount = 0;
for (auto adapter : adapters) {
    uint32_t adapterPlatformCount = 0;
    urPlatformGet(adapter, 0, nullptr, &adapterPlatformCount);
    platforms.reserve(platformCount + adapterPlatformCount);
    urPlatformGet(adapter, adapterPlatformCount,
                           &platforms[platformCount], &adapterPlatformCount);
    platformCount += adapterPlatformCount;
}
platforms.resize(platformCount);

(error handling removed for brevity)

The second call to urPlatformGet invokes undefined behavior because platforms.size() is 0, the element access is out of bounds. The fact that the underlying allocation has been grown is not a guarantee from the standard that elements can be accessed.

In practice this implementation seems to depend on vector.resize() not changing elements within capacity, which is not required. With glibc in debug mode I can observe the hello_world example triggering a segmentation fault due to platforms.resize(platformCount) setting all elements of platforms to nullptr.

To reproduce

  • Build the hello_world example in debug mode.
  • Run on a device with the OpenCL adapter
  • Observe segmentation fault

Environment

  • OS: Linux
  • Target device and vendor: Intel CPU
  • DPC++ version: N/A
  • Dependencies version: N/A

Additional context

The bug seems to have been introduced in #17876

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions