Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add VK_IMPLICIT_LAYER_PATH & VK_ADD_IMPLICIT_LAYER_PATH env-vars #1550

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 13 additions & 8 deletions docs/LoaderApplicationInterface.md
Original file line number Diff line number Diff line change
Expand Up @@ -472,18 +472,23 @@ This can be accomplished in one of two ways:
[VkConfig](https://github.com/LunarG/VulkanTools/blob/main/vkconfig/README.md)
tool shipped with the Vulkan SDK.
2. Directing the loader to look for layers in specific files and/or folders by using the
`VK_LAYER_PATH` environment variable.
`VK_LAYER_PATH` and/or `VK_IMPLICIT_LAYER_PATH` environment variables.

The `VK_LAYER_PATH` environment variable can contain multiple paths separated by
the operating-system specific path separator.
The `VK_LAYER_PATH` and `VK_IMPLICIT_LAYER_PATH` environment variables can contain multiple
paths separated by the operating-system specific path separator.
On Windows, this is a semicolon (`;`), while on Linux and macOS it is a colon
(`:`).

If `VK_LAYER_PATH` exists, the files and/or folders listed will be scanned for explicit
layer manifest files.
Implicit layer discovery is unaffected by this environment variable.
Each directory listed should be the full pathname of a folder containing layer
manifest files.

If `VK_IMPLICIT_LAYER_PATH` exists, the files and/or folders listed will be scanned for
implicit layer manifest files.
Explicit layer discovery is unaffected by this environment variable.

Each directory listed in `VK_LAYER_PATH` and `VK_IMPLICIT_LAYER_PATH` should be the full
pathname of a folder containing layer manifest files.

See the
[Table of Debug Environment Variables](LoaderInterfaceArchitecture.md#table-of-debug-environment-variables)
Expand All @@ -493,9 +498,9 @@ for more details.

#### Exception for Elevated Privileges

For security reasons, `VK_LAYER_PATH` is ignored if running with elevated
privileges.
Because of this, `VK_LAYER_PATH` can only be used for applications that do not
For security reasons, `VK_LAYER_PATH` and `VK_IMPLICIT_LAYER_PATH` are ignored if running
with elevated privileges.
Because of this, the environment variables can only be used for applications that do not
use elevated privileges.

For more information see
Expand Down
56 changes: 52 additions & 4 deletions docs/LoaderInterfaceArchitecture.md
Original file line number Diff line number Diff line change
Expand Up @@ -430,6 +430,8 @@ These behaviors also result in ignoring certain environment variables, such as:
* `VK_ADD_DRIVER_FILES`
* `VK_LAYER_PATH`
* `VK_ADD_LAYER_PATH`
* `VK_IMPLICIT_LAYER_PATH`
* `VK_ADD_IMPLICIT_LAYER_PATH`
* `XDG_CONFIG_HOME` (Linux/Mac-specific)
* `XDG_DATA_HOME` (Linux/Mac-specific)

Expand Down Expand Up @@ -606,8 +608,8 @@ discovery.
</small></td>
<td><small>
Provide a list of additional paths that the loader will use to search
for layers in addition to the loader's standard Layer library search
folder when looking for explicit layer manifest files.
for explicit layers in addition to the loader's standard layer library
search paths when looking for layer manifest files.
The paths will be added first, prior to the list of folders that would
be searched normally.
</small></td>
Expand All @@ -624,6 +626,31 @@ discovery.
&nbsp;&nbsp;VK_ADD_LAYER_PATH=<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;path_a&gt;;&lt;path_b&gt;</small>
</td>
</tr>
<tr>
<td><small>
<i>VK_ADD_IMPLICIT_LAYER_PATH</i>
</small></td>
<td><small>
Provide a list of additional paths that the loader will use to search
for implicit layers in addition to the loader's standard layer library
search paths when looking for layer manifest files.
The paths will be added first, prior to the list of folders that would
be searched normally.
</small></td>
<td><small>
<a href="#elevated-privilege-caveats">
Ignored when running Vulkan application with elevated privileges.
</a>
</small></td>
<td><small>
export<br/>
&nbsp;&nbsp;VK_ADD_IMPLICIT_LAYER_PATH=<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;path_a&gt;:&lt;path_b&gt;<br/><br/>
set<br/>
&nbsp;&nbsp;VK_ADD_IMPLICIT_LAYER_PATH=<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;path_a&gt;;&lt;path_b&gt;</small>
</td>
</tr>
<tr>
<td><small>
Expand Down Expand Up @@ -661,8 +688,8 @@ discovery.
<td><small>
<i>VK_LAYER_PATH</i></small></td>
<td><small>
Override the loader's standard Layer library search folders and use the
provided delimited file and/or folders to locate explicit layer manifest files.
Override the loader's standard explicit layer search paths and use the
provided delimited files and/or folders to locate layer manifest files.
</small></td>
<td><small>
<a href="#elevated-privilege-caveats">
Expand All @@ -678,6 +705,27 @@ discovery.
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;path_a&gt;;&lt;path_b&gt;
</small></td>
</tr>
<tr>
<td><small>
<i>VK_IMPLICIT_LAYER_PATH</i></small></td>
<td><small>
Override the loader's standard implicit layer search paths and use the
provided delimited files and/or folders to locate layer manifest files.
</small></td>
<td><small>
<a href="#elevated-privilege-caveats">
Ignored when running Vulkan application with elevated privileges.
</a>
</small></td>
<td><small>
export<br/>
&nbsp;&nbsp;VK_IMPLICIT_LAYER_PATH=<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;path_a&gt;:&lt;path_b&gt;<br/><br/>
set<br/>
&nbsp;&nbsp;VK_IMPLICIT_LAYER_PATH=<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;path_a&gt;;&lt;path_b&gt;
</small></td>
</tr>
<tr>
<td><small>
<i>VK_LOADER_DEBUG</i>
Expand Down
54 changes: 39 additions & 15 deletions docs/LoaderLayerInterface.md
Original file line number Diff line number Diff line change
Expand Up @@ -256,8 +256,18 @@ of search folders and will therefore be searched first.
If `VK_LAYER_PATH` is present, then `VK_ADD_LAYER_PATH` will not be used by the
loader and any values will be ignored.

For security reasons, both `VK_LAYER_PATH` and `VK_ADD_LAYER_PATH` are ignored
if running with elevated privileges.
If `VK_IMPLICIT_LAYER_PATH` is defined, then the loader will look at the paths
defined by that variable for implicit layer manifest files instead of using the
information provided by the implicit layer registry keys.

If `VK_ADD_IMPLICIT_LAYER_PATH` is defined, then the loader will look at the provided
paths for implicit layer manifest files in addition to using the information
provided by the implicit layer registry keys.
The paths provided by `VK_ADD_IMPLICIT_LAYER_PATH` are added before the standard list
of search folders and will therefore be searched first.

For security reasons, `VK_LAYER_PATH`, `VK_ADD_LAYER_PATH`, `VK_IMPLICIT_LAYER_PATH`,
and `VK_ADD_IMPLICIT_LAYER_PATH` are ignored if running with elevated privileges.
See [Exception for Elevated Privileges](#exception-for-elevated-privileges)
for more info.

Expand Down Expand Up @@ -353,8 +363,21 @@ of search folders and will therefore be searched first.
If `VK_LAYER_PATH` is present, then `VK_ADD_LAYER_PATH` will not be used by the
loader and any values will be ignored.

For security reasons, both `VK_LAYER_PATH` and `VK_ADD_LAYER_PATH` are ignored
if running with elevated privileges.
If `VK_IMPLICIT_LAYER_PATH` is defined, then the loader will look at the paths
defined by that variable for implicit layer manifest files instead of using the
information provided by the standard implicit layer paths mentioned above.

If `VK_ADD_IMPLICIT_LAYER_PATH` is defined, then the loader will look at the
provided paths for implicit layer manifest files in addition to using the
information provided by the standard implicit layer paths mentioned above.
The paths provided by `VK_ADD_IMPLICIT_LAYER_PATH` are added before the standard
list of search folders and will therefore be searched first.

If `VK_IMPLICIT_LAYER_PATH` is present, then `VK_ADD_IMPLICIT_LAYER_PATH` will
not be used by the loader and any values will be ignored.

For security reasons, `VK_LAYER_PATH`, `VK_ADD_LAYER_PATH`, `VK_IMPLICIT_LAYER_PATH`,
and `VK_ADD_IMPLICIT_LAYER_PATH` are ignored if running with elevated privileges.
See [Exception for Elevated Privileges](#exception-for-elevated-privileges)
for more info.

Expand All @@ -367,10 +390,10 @@ See
in the [LoaderApplicationInterface.md document](LoaderApplicationInterface.md)
for more information on this.

It is also important to note that while both `VK_LAYER_PATH` and
`VK_ADD_LAYER_PATH` will point the loader paths to search for finding the
manifest files, it does not guarantee the library files mentioned by the
manifest will immediately be found.
It is also important to note that while `VK_LAYER_PATH`, `VK_ADD_LAYER_PATH`,
`VK_IMPLICIT_LAYER_PATH`, and `VK_ADD_IMPLICIT_LAYER_PATH` will point the
loader at paths to search for finding the manifest files, it does not guarantee
the library files mentioned by the manifest will immediately be found.
Often, the layer manifest file will point to the library file using a relative
or absolute path.
When a relative or absolute path is used, the loader can typically find the
Expand Down Expand Up @@ -438,8 +461,8 @@ following:
The loader supports filter environment variables which can forcibly enable and
disable known layers.
Known layers are those that are already found by the loader taking into account
default search paths and other environment variables
(like `VK_LAYER_PATH` or `VK_ADD_LAYER_PATH`).
default search paths and environment variables `VK_LAYER_PATH`, `VK_ADD_LAYER_PATH`,
`VK_IMPLICIT_LAYER_PATH`, and `VK_ADD_IMPLICIT_LAYER_PATH`.

The filter variables will be compared against the layer name provided in the
layer's manifest file.
Expand Down Expand Up @@ -548,8 +571,9 @@ override any disables supplied in `VK_LOADER_LAYERS_DISABLE`.

### Exception for Elevated Privileges

For security reasons, `VK_LAYER_PATH` and `VK_ADD_LAYER_PATH` are ignored if
running the Vulkan application with elevated privileges.
For security reasons, `VK_LAYER_PATH`, `VK_ADD_LAYER_PATH`, `VK_IMPLICIT_LAYER_PATH`
and `VK_ADD_IMPLICIT_LAYER_PATH` are ignored if running the Vulkan application
with elevated privileges.
This is because they may insert new libraries into the executable process that
are not normally found by the loader.
Because of this, these environment variables can only be used for applications
Expand Down Expand Up @@ -2696,9 +2720,9 @@ Android Vulkan documentation</a>.
<tr>
<td><small><b>LLP_LOADER_13</b></small></td>
<td>A loader <b>must</b> not load from user-defined paths (including the
use of either <i>VK_LAYER_PATH</i> or <i>VK_ADD_LAYER_PATH</i>
environment variables) when running elevated (Administrator/Super-user)
applications.<br/>
use of <i>VK_LAYER_PATH</i>, <i>VK_ADD_LAYER_PATH</i>, <i>VK_IMPLICIT_LAYER_PATH</i>,
or <i>VK_ADD_IMPLICIT_LAYER_PATH</i> environment variables) when running
elevated (Administrator/Super-user) applications.<br/>
<b>This is for security reasons.</b>
</td>
<td>The behavior is undefined and may result in computer security lapses,
Expand Down
6 changes: 4 additions & 2 deletions loader/loader.c
Original file line number Diff line number Diff line change
Expand Up @@ -3148,6 +3148,8 @@ VkResult read_data_files_in_search_paths(const struct loader_instance *inst, enu
#endif
break;
case LOADER_DATA_FILE_MANIFEST_IMPLICIT_LAYER:
override_env = loader_secure_getenv(VK_IMPLICIT_LAYER_PATH_ENV_VAR, inst);
additional_env = loader_secure_getenv(VK_ADDITIONAL_IMPLICIT_LAYER_PATH_ENV_VAR, inst);
#if COMMON_UNIX_PLATFORMS
relative_location = VK_ILAYERS_INFO_RELATIVE_DIR;
#endif
Expand All @@ -3156,8 +3158,8 @@ VkResult read_data_files_in_search_paths(const struct loader_instance *inst, enu
#endif
break;
case LOADER_DATA_FILE_MANIFEST_EXPLICIT_LAYER:
override_env = loader_secure_getenv(VK_LAYER_PATH_ENV_VAR, inst);
additional_env = loader_secure_getenv(VK_ADDITIONAL_LAYER_PATH_ENV_VAR, inst);
override_env = loader_secure_getenv(VK_EXPLICIT_LAYER_PATH_ENV_VAR, inst);
additional_env = loader_secure_getenv(VK_ADDITIONAL_EXPLICIT_LAYER_PATH_ENV_VAR, inst);
#if COMMON_UNIX_PLATFORMS
relative_location = VK_ELAYERS_INFO_RELATIVE_DIR;
#endif
Expand Down
7 changes: 5 additions & 2 deletions loader/vk_loader_platform.h
Original file line number Diff line number Diff line change
Expand Up @@ -100,10 +100,10 @@
// Environment Variable information
#define VK_ICD_FILENAMES_ENV_VAR "VK_ICD_FILENAMES" // Deprecated in v1.3.207 loader
#define VK_DRIVER_FILES_ENV_VAR "VK_DRIVER_FILES"
#define VK_LAYER_PATH_ENV_VAR "VK_LAYER_PATH"
#define VK_EXPLICIT_LAYER_PATH_ENV_VAR "VK_LAYER_PATH"
// Support added in v1.3.207 loader
#define VK_ADDITIONAL_DRIVER_FILES_ENV_VAR "VK_ADD_DRIVER_FILES"
#define VK_ADDITIONAL_LAYER_PATH_ENV_VAR "VK_ADD_LAYER_PATH"
#define VK_ADDITIONAL_EXPLICIT_LAYER_PATH_ENV_VAR "VK_ADD_LAYER_PATH"
// Support added in v1.3.234 loader
#define VK_LAYERS_ENABLE_ENV_VAR "VK_LOADER_LAYERS_ENABLE"
#define VK_LAYERS_DISABLE_ENV_VAR "VK_LOADER_LAYERS_DISABLE"
Expand All @@ -115,6 +115,9 @@
#define VK_LOADER_DISABLE_ALL_LAYERS_VAR_3 "**"
#define VK_LOADER_DISABLE_IMPLICIT_LAYERS_VAR "~implicit~"
#define VK_LOADER_DISABLE_EXPLICIT_LAYERS_VAR "~explicit~"
// Support added in v1.3.295 loader
#define VK_IMPLICIT_LAYER_PATH_ENV_VAR "VK_IMPLICIT_LAYER_PATH"
#define VK_ADDITIONAL_IMPLICIT_LAYER_PATH_ENV_VAR "VK_ADD_IMPLICIT_LAYER_PATH"

// Override layer information
#define VK_OVERRIDE_LAYER_NAME "VK_LAYER_LUNARG_override"
Expand Down
3 changes: 3 additions & 0 deletions tests/framework/shim/shim_common.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,9 @@ void PlatformShim::redirect_category(std::filesystem::path const& new_path, Mani
if (category == ManifestCategory::explicit_layer) {
parse_and_add_env_var_override(paths, get_env_var("VK_LAYER_PATH", false)); // don't report failure
}
if (category == ManifestCategory::implicit_layer) {
parse_and_add_env_var_override(paths, get_env_var("VK_IMPLICIT_LAYER_PATH", false)); // don't report failure
}
parse_and_add_env_var_override(paths, FALLBACK_DATA_DIRS);
parse_and_add_env_var_override(paths, FALLBACK_CONFIG_DIRS);

Expand Down
42 changes: 32 additions & 10 deletions tests/framework/test_environment.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -400,6 +400,8 @@ FrameworkEnvironment::FrameworkEnvironment(FrameworkSettings const& settings) no
folders.emplace_back(FRAMEWORK_BUILD_DIRECTORY, std::string("explicit_env_var_layer_folder"));
folders.emplace_back(FRAMEWORK_BUILD_DIRECTORY, std::string("explicit_add_env_var_layer_folder"));
folders.emplace_back(FRAMEWORK_BUILD_DIRECTORY, std::string("implicit_layer_manifests"));
folders.emplace_back(FRAMEWORK_BUILD_DIRECTORY, std::string("implicit_env_var_layer_manifests"));
folders.emplace_back(FRAMEWORK_BUILD_DIRECTORY, std::string("implicit_add_env_var_layer_manifests"));
folders.emplace_back(FRAMEWORK_BUILD_DIRECTORY, std::string("override_layer_manifests"));
folders.emplace_back(FRAMEWORK_BUILD_DIRECTORY, std::string("app_package_manifests"));
folders.emplace_back(FRAMEWORK_BUILD_DIRECTORY, std::string("macos_bundle"));
Expand Down Expand Up @@ -579,20 +581,40 @@ void FrameworkEnvironment::add_layer_impl(TestLayerDetails layer_details, Manife
if (category == ManifestCategory::implicit_layer) fs_ptr = &get_folder(ManifestLocation::implicit_layer);
break;
case (ManifestDiscoveryType::env_var):
fs_ptr = &get_folder(ManifestLocation::explicit_layer_env_var);
if (layer_details.is_dir) {
env_var_vk_layer_paths.add_to_list(narrow(fs_ptr->location()));
} else {
env_var_vk_layer_paths.add_to_list(narrow(fs_ptr->location() / layer_details.json_name));
if (category == ManifestCategory::explicit_layer) {
fs_ptr = &get_folder(ManifestLocation::explicit_layer_env_var);
if (layer_details.is_dir) {
env_var_vk_layer_paths.add_to_list(narrow(fs_ptr->location()));
} else {
env_var_vk_layer_paths.add_to_list(narrow(fs_ptr->location() / layer_details.json_name));
}
}
if (category == ManifestCategory::implicit_layer) {
fs_ptr = &get_folder(ManifestLocation::implicit_layer_env_var);
if (layer_details.is_dir) {
env_var_vk_implicit_layer_paths.add_to_list(narrow(fs_ptr->location()));
} else {
env_var_vk_implicit_layer_paths.add_to_list(narrow(fs_ptr->location() / layer_details.json_name));
}
}
platform_shim->add_known_path(fs_ptr->location());
break;
case (ManifestDiscoveryType::add_env_var):
fs_ptr = &get_folder(ManifestLocation::explicit_layer_add_env_var);
if (layer_details.is_dir) {
add_env_var_vk_layer_paths.add_to_list(narrow(fs_ptr->location()));
} else {
add_env_var_vk_layer_paths.add_to_list(narrow(fs_ptr->location() / layer_details.json_name));
if (category == ManifestCategory::explicit_layer) {
fs_ptr = &get_folder(ManifestLocation::explicit_layer_add_env_var);
if (layer_details.is_dir) {
add_env_var_vk_layer_paths.add_to_list(narrow(fs_ptr->location()));
} else {
add_env_var_vk_layer_paths.add_to_list(narrow(fs_ptr->location() / layer_details.json_name));
}
}
if (category == ManifestCategory::implicit_layer) {
fs_ptr = &get_folder(ManifestLocation::implicit_layer_add_env_var);
if (layer_details.is_dir) {
add_env_var_vk_implicit_layer_paths.add_to_list(narrow(fs_ptr->location()));
} else {
add_env_var_vk_implicit_layer_paths.add_to_list(narrow(fs_ptr->location() / layer_details.json_name));
}
}
platform_shim->add_known_path(fs_ptr->location());
break;
Expand Down
14 changes: 9 additions & 5 deletions tests/framework/test_environment.h
Original file line number Diff line number Diff line change
Expand Up @@ -621,11 +621,13 @@ enum class ManifestLocation {
explicit_layer_env_var = 4,
explicit_layer_add_env_var = 5,
implicit_layer = 6,
override_layer = 7,
windows_app_package = 8,
macos_bundle = 9,
unsecured_location = 10,
settings_location = 11,
implicit_layer_env_var = 7,
implicit_layer_add_env_var = 8,
override_layer = 9,
windows_app_package = 10,
macos_bundle = 11,
unsecured_location = 12,
settings_location = 13,
};

struct FrameworkSettings {
Expand Down Expand Up @@ -697,6 +699,8 @@ struct FrameworkEnvironment {
EnvVarWrapper add_env_var_vk_icd_filenames{"VK_ADD_DRIVER_FILES"};
EnvVarWrapper env_var_vk_layer_paths{"VK_LAYER_PATH"};
EnvVarWrapper add_env_var_vk_layer_paths{"VK_ADD_LAYER_PATH"};
EnvVarWrapper env_var_vk_implicit_layer_paths{"VK_IMPLICIT_LAYER_PATH"};
EnvVarWrapper add_env_var_vk_implicit_layer_paths{"VK_ADD_IMPLICIT_LAYER_PATH"};

LoaderSettings loader_settings; // the current settings written to disk
private:
Expand Down
Loading