KhronosGroup / KhronosGroup/Vulkan-Loader

Relative path ICD is not deterministic, can return duplicate entry

Open
#2,017 4 comments 0 reactions 0 assignees View on GitHub
bug
Dominant language
C
Stars
695
Forks
343
Avg merge
1d 1h
Merged PRs (30d)
17

Description

**Describe the bug**
I am helping conda-forge in integrating other directories for ICDs so that we can have:

1. THe system ICDs
2. The conda-forge installed ICDs

However, the problem is that the ubuntu ICD loader reads:

```
/usr/share/vulkan/icd.d $ cat intel_icd.json
{
"ICD": {
"api_version": "1.4.318",
"library_path": "libvulkan_intel.so"
},
"file_format_version": "1.0.1"
}
```

With conda installing its own `libvulkan_intel.so` this will eventually resolve to conda's version. My claim is that we can't do anything about this other than ask ubuntu to use the full path for ICD libraries (which they likely won't do)

Conda will also install its own icd.json file, to its own `${CONDA_PREFIX}/share/vulkan/icd.d`, and thus the same library will appear twice.

I think we should filter it out, just to keep the output less confusing.

- xref: https://github.com/conda-forge/vulkan-loader-feedstock/pull/35
- xref: https://github.com/conda-forge/mesalib-feedstock/pull/150

**Environment (please complete the following information):**
- OS: ubuntu 24 + conda(-forge)
- Bitdepth: 64bit
- GPU: intel (well anything really)
- Graphics Driver: mesa 26
- SDK or header version if building from repo: 1.4.357.0
- Enabled layers:

**To Reproduce**
```
diff --git a/loader/loader.c b/loader/loader.c
--- a/loader/loader.c
+++ b/loader/loader.c
@@ -2145,6 +2145,31 @@
goto out;
}

+ // Skip a driver we have already scanned. Two different manifests can name the same
+ // library: a distribution manifest using a bare "library_path" resolved through the
+ // dynamic linker search path, and one using an absolute path, can both end up at the
+ // same file. The duplicate checks elsewhere in the loader only compare path strings,
+ // so nothing catches this and the driver is scanned twice, which reports every
+ // physical device it owns twice from vkEnumeratePhysicalDevices.
+ //
+ // dlopen/LoadLibrary returns the same handle for an object that is already loaded, so
+ // comparing handles identifies the duplicate exactly, without resolving paths or
+ // stat()ing anything. Keep the entry already in the list: the search order puts the
+ // more specific manifest first.
+ for (uint32_t i = 0; i < icd_tramp_list->count; i++) {
+ if (icd_tramp_list->scanned_list[i].handle == handle) {
+ loader_log(inst, VULKAN_LOADER_INFO_BIT | VULKAN_LOADER_DRIVER_BIT, 0,
+ "loader_scanned_icd_add: Driver %s is the same library as already loaded driver %s, skipping duplicate",
+ filename, icd_tramp_list->scanned_list[i].lib_name);
+ // Release the reference the open above took; the existing entry owns the one
+ // that loader_scanned_icd_clear will release.
+ loader_platform_close_library(handle);
+ handle = NULL;
+ res = VK_SUCCESS;
+ goto out;
+ }
+ }
+
// Try to load the driver's exported vk_icdNegotiateLoaderICDInterfaceVersion
fp_negotiate_icd_version = loader_platform_get_proc_address(handle, "vk_icdNegotiateLoaderICDInterfaceVersion");

```

**VK_LOADER_DEBUG output**
Attach output when running with the environment variable VK_LOADER_DEBUG=all

**Additional context**

Contributor guide

Open the contributing guide

Research direction

Start in loader/loader.c around the ICD scanning code shown in the reproduction, especially loader_scanned_icd_add. Reproduce the Ubuntu and conda-forge manifests with VK_LOADER_DEBUG=all, then verify that manifests resolving to the same library produce one driver and one set of physical devices rather than duplicates.

Written by the indexing model from the issue text.

Assessment

Tech stack
c
Domain
api, backend
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
68/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.