mirror of
https://github.com/openharmony/third_party_vulkan-loader.git
synced 2026-07-19 17:13:36 -04:00
Enable testing of high-integrity in the loader
Enable testing to check if the loader is running with elevated privileges. This is to make sure we're ignoring the appropriate environment variables in those scenarios to potentially avoid escalation exploits.
This commit is contained in:
+6
-8
@@ -2969,13 +2969,11 @@ static VkResult read_data_files_in_search_paths(const struct loader_instance *in
|
||||
if (path_override != NULL) {
|
||||
override_path = path_override;
|
||||
} else if (env_override != NULL) {
|
||||
#ifndef _WIN32
|
||||
if (geteuid() != getuid() || getegid() != getgid()) {
|
||||
// Don't allow setuid apps to use the env var:
|
||||
env_override = NULL;
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
// Don't allow setuid apps to use the env var
|
||||
if (is_high_integrity()) {
|
||||
loader_log(inst, VULKAN_LOADER_WARN_BIT, 0,
|
||||
"read_data_files_in_search_paths: Ignoring override %s due to high-integrity", env_override);
|
||||
} else {
|
||||
override_env = loader_secure_getenv(env_override, inst);
|
||||
|
||||
// The ICD override is actually a specific list of filenames, not directories
|
||||
@@ -3065,7 +3063,7 @@ static VkResult read_data_files_in_search_paths(const struct loader_instance *in
|
||||
cur_path_ptr += rel_size;
|
||||
*cur_path_ptr++ = PATH_SEPARATOR;
|
||||
// only for ICD manifests
|
||||
if (env_override != NULL && strcmp(VK_ICD_FILENAMES_ENV_VAR, env_override) == 0) {
|
||||
if (!is_high_integrity() && env_override != NULL && strcmp(VK_ICD_FILENAMES_ENV_VAR, env_override) == 0) {
|
||||
use_first_found_manifest = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* Copyright (c) 2021 The Khronos Group Inc.
|
||||
* Copyright (c) 2021 Valve Corporation
|
||||
* Copyright (c) 2021 LunarG, Inc.
|
||||
* Copyright (c) 2021-2022 The Khronos Group Inc.
|
||||
* Copyright (c) 2021-2022 Valve Corporation
|
||||
* Copyright (c) 2021-2022 LunarG, Inc.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and/or associated documentation files (the "Materials"), to
|
||||
@@ -132,8 +132,8 @@ struct PlatformShim {
|
||||
// platform specific shim interface
|
||||
#if defined(WIN32)
|
||||
// Control Platform Elevation Level
|
||||
void set_elevated_privilege(bool elev) { (elev) ? SECURITY_MANDATORY_HIGH_RID : SECURITY_MANDATORY_LOW_RID; }
|
||||
unsigned long elevation_level = SECURITY_MANDATORY_LOW_RID;
|
||||
void set_elevation_level(unsigned long new_elevation_level) { elevation_level = new_elevation_level; }
|
||||
|
||||
void add_dxgi_adapter(fs::path const& manifest_path, GpuType gpu_preference, uint32_t known_driver_index,
|
||||
DXGI_ADAPTER_DESC1 desc1);
|
||||
@@ -162,6 +162,8 @@ struct PlatformShim {
|
||||
|
||||
std::unordered_map<std::string, fs::path> redirection_map;
|
||||
|
||||
void set_elevated_privilege(bool elev) { use_fake_elevation = elev; }
|
||||
bool use_fake_elevation = false;
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* Copyright (c) 2021 The Khronos Group Inc.
|
||||
* Copyright (c) 2021 Valve Corporation
|
||||
* Copyright (c) 2021 LunarG, Inc.
|
||||
* Copyright (c) 2021-2022 The Khronos Group Inc.
|
||||
* Copyright (c) 2021-2022 Valve Corporation
|
||||
* Copyright (c) 2021-2022 LunarG, Inc.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and/or associated documentation files (the "Materials"), to
|
||||
@@ -46,19 +46,27 @@ FRAMEWORK_EXPORT PlatformShim* get_platform_shim() {
|
||||
#define OPENDIR_FUNC_NAME opendir
|
||||
#define ACCESS_FUNC_NAME access
|
||||
#define FOPEN_FUNC_NAME fopen
|
||||
#define GETEUID_FUNC_NAME geteuid
|
||||
#define GETEGID_FUNC_NAME getegid
|
||||
#elif defined(__APPLE__)
|
||||
#define OPENDIR_FUNC_NAME my_opendir
|
||||
#define ACCESS_FUNC_NAME my_access
|
||||
#define FOPEN_FUNC_NAME my_fopen
|
||||
#define GETEUID_FUNC_NAME my_geteuid
|
||||
#define GETEGID_FUNC_NAME my_getegid
|
||||
#endif
|
||||
|
||||
using PFN_OPENDIR = DIR* (*)(const char* path_name);
|
||||
using PFN_ACCESS = int (*)(const char* pathname, int mode);
|
||||
using PFN_FOPEN = FILE* (*)(const char* filename, const char* mode);
|
||||
using PFN_GETEUID = uid_t (*)(void);
|
||||
using PFN_GETEGID = gid_t (*)(void);
|
||||
|
||||
static PFN_OPENDIR real_opendir = nullptr;
|
||||
static PFN_ACCESS real_access = nullptr;
|
||||
static PFN_FOPEN real_fopen = nullptr;
|
||||
static PFN_GETEUID real_geteuid = nullptr;
|
||||
static PFN_GETEGID real_getegid = nullptr;
|
||||
|
||||
FRAMEWORK_EXPORT DIR* OPENDIR_FUNC_NAME(const char* path_name) {
|
||||
if (!real_opendir) real_opendir = (PFN_OPENDIR)dlsym(RTLD_NEXT, "opendir");
|
||||
@@ -109,6 +117,28 @@ FRAMEWORK_EXPORT FILE* FOPEN_FUNC_NAME(const char* in_filename, const char* mode
|
||||
return f_ptr;
|
||||
}
|
||||
|
||||
FRAMEWORK_EXPORT uid_t GETEUID_FUNC_NAME(void) {
|
||||
if (!real_geteuid) real_geteuid = (PFN_GETEUID)dlsym(RTLD_NEXT, "geteuid");
|
||||
|
||||
if (platform_shim.use_fake_elevation) {
|
||||
// Root on linux is 0, so force pretending like we're root
|
||||
return 0;
|
||||
} else {
|
||||
return real_geteuid();
|
||||
}
|
||||
}
|
||||
|
||||
FRAMEWORK_EXPORT gid_t GETEGID_FUNC_NAME(void) {
|
||||
if (!real_getegid) real_getegid = (PFN_GETEGID)dlsym(RTLD_NEXT, "getegid");
|
||||
|
||||
if (platform_shim.use_fake_elevation) {
|
||||
// Root on linux is 0, so force pretending like we're root
|
||||
return 0;
|
||||
} else {
|
||||
return real_getegid();
|
||||
}
|
||||
}
|
||||
|
||||
/* Shiming functions on apple is limited by the linker prefering to not use functions in the
|
||||
* executable in loaded dylibs. By adding an interposer, we redirect the linker to use our
|
||||
* version of the function over the real one, thus shimming the system function.
|
||||
@@ -125,5 +155,7 @@ struct Interposer {
|
||||
__attribute__((used)) static Interposer _interpose_opendir MACOS_ATTRIB = {VOIDP_CAST(my_opendir), VOIDP_CAST(opendir)};
|
||||
__attribute__((used)) static Interposer _interpose_access MACOS_ATTRIB = {VOIDP_CAST(my_access), VOIDP_CAST(access)};
|
||||
__attribute__((used)) static Interposer _interpose_fopen MACOS_ATTRIB = {VOIDP_CAST(my_fopen), VOIDP_CAST(fopen)};
|
||||
__attribute__((used)) static Interposer _interpose_euid MACOS_ATTRIB = {VOIDP_CAST(my_geteuid), VOIDP_CAST(geteuid)};
|
||||
__attribute__((used)) static Interposer _interpose_egid MACOS_ATTRIB = {VOIDP_CAST(my_getegid), VOIDP_CAST(getegid)};
|
||||
#endif
|
||||
} // extern "C"
|
||||
|
||||
@@ -2131,15 +2131,30 @@ TEST(EnvironmentVariables, VK_LAYER_PATH) {
|
||||
ManifestLayer::LayerDescription{}.set_name(layer_name).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)),
|
||||
"test_layer.json");
|
||||
|
||||
InstWrapper inst{env.vulkan_functions};
|
||||
inst.create_info.add_layer(layer_name);
|
||||
FillDebugUtilsCreateDetails(inst.create_info, env.debug_log);
|
||||
inst.CheckCreate();
|
||||
InstWrapper inst1{env.vulkan_functions};
|
||||
inst1.create_info.add_layer(layer_name);
|
||||
FillDebugUtilsCreateDetails(inst1.create_info, env.debug_log);
|
||||
inst1.CheckCreate();
|
||||
|
||||
// look for VK_LAYER_PATHS
|
||||
EXPECT_TRUE(env.debug_log.find("/tmp/carol"));
|
||||
EXPECT_TRUE(env.debug_log.find("/tandy"));
|
||||
EXPECT_TRUE(env.debug_log.find((HOME / "/ with spaces/").str()));
|
||||
EXPECT_FALSE(env.debug_log.find("Ignoring override VK_LAYER_PATH due to high-integrity"));
|
||||
|
||||
env.debug_log.clear();
|
||||
|
||||
env.platform_shim->set_elevated_privilege(true);
|
||||
|
||||
InstWrapper inst2{env.vulkan_functions};
|
||||
inst2.create_info.add_layer(layer_name);
|
||||
FillDebugUtilsCreateDetails(inst2.create_info, env.debug_log);
|
||||
inst2.CheckCreate();
|
||||
|
||||
EXPECT_TRUE(env.debug_log.find("Ignoring override VK_LAYER_PATH due to high-integrity"));
|
||||
EXPECT_FALSE(env.debug_log.find("/tmp/carol"));
|
||||
|
||||
env.platform_shim->set_elevated_privilege(false);
|
||||
|
||||
remove_env_var("VK_LAYER_PATH");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user