#include "loader_environment.h"
#include "allocation.h"
#include "loader.h"
#include "log.h"
#include <ctype.h>
#if COMMON_UNIX_PLATFORMS
bool is_high_integrity() { … }
char *loader_getenv(const char *name, const struct loader_instance *inst) { … }
char *loader_secure_getenv(const char *name, const struct loader_instance *inst) { … }
void loader_free_getenv(char *val, const struct loader_instance *inst) { … }
#elif defined(WIN32)
bool is_high_integrity() {
HANDLE process_token;
if (OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY | TOKEN_QUERY_SOURCE, &process_token)) {
uint8_t mandatory_label_buffer[SECURITY_MAX_SID_SIZE + sizeof(DWORD)];
DWORD buffer_size;
if (GetTokenInformation(process_token, TokenIntegrityLevel, mandatory_label_buffer, sizeof(mandatory_label_buffer),
&buffer_size) != 0) {
const TOKEN_MANDATORY_LABEL *mandatory_label = (const TOKEN_MANDATORY_LABEL *)mandatory_label_buffer;
const DWORD sub_authority_count = *GetSidSubAuthorityCount(mandatory_label->Label.Sid);
const DWORD integrity_level = *GetSidSubAuthority(mandatory_label->Label.Sid, sub_authority_count - 1);
CloseHandle(process_token);
return integrity_level >= SECURITY_MANDATORY_HIGH_RID;
}
CloseHandle(process_token);
}
return false;
}
char *loader_getenv(const char *name, const struct loader_instance *inst) {
int name_utf16_size = MultiByteToWideChar(CP_UTF8, 0, name, -1, NULL, 0);
if (name_utf16_size <= 0) {
return NULL;
}
wchar_t *name_utf16 = (wchar_t *)loader_stack_alloc(name_utf16_size * sizeof(wchar_t));
if (MultiByteToWideChar(CP_UTF8, 0, name, -1, name_utf16, name_utf16_size) != name_utf16_size) {
return NULL;
}
DWORD val_size = GetEnvironmentVariableW(name_utf16, NULL, 0);
if (val_size == 0) {
return NULL;
}
wchar_t *val = (wchar_t *)loader_stack_alloc(val_size * sizeof(wchar_t));
if (GetEnvironmentVariableW(name_utf16, val, val_size) != val_size - 1) {
return NULL;
}
int val_utf8_size = WideCharToMultiByte(CP_UTF8, 0, val, -1, NULL, 0, NULL, NULL);
if (val_utf8_size <= 0) {
return NULL;
}
char *val_utf8 = (char *)loader_instance_heap_alloc(inst, val_utf8_size * sizeof(char), VK_SYSTEM_ALLOCATION_SCOPE_COMMAND);
if (val_utf8 == NULL) {
return NULL;
}
if (WideCharToMultiByte(CP_UTF8, 0, val, -1, val_utf8, val_utf8_size, NULL, NULL) != val_utf8_size) {
loader_instance_heap_free(inst, val_utf8);
return NULL;
}
return val_utf8;
}
char *loader_secure_getenv(const char *name, const struct loader_instance *inst) {
if (NULL == name) return NULL;
#if !defined(LOADER_USE_UNSAFE_FILE_SEARCH)
if (is_high_integrity()) {
loader_log(inst, VULKAN_LOADER_INFO_BIT, 0,
"Loader is running with elevated permissions. Environment variable %s will be ignored", name);
return NULL;
}
#endif
return loader_getenv(name, inst);
}
void loader_free_getenv(char *val, const struct loader_instance *inst) { loader_instance_heap_free(inst, (void *)val); }
#else
#warning \
"This platform does not support environment variables! If this is not intended, please implement the stubs functions loader_getenv and loader_free_getenv"
char *loader_getenv(const char *name, const struct loader_instance *inst) {
(void)inst;
(void)name;
return NULL;
}
void loader_free_getenv(char *val, const struct loader_instance *inst) {
(void)val;
(void)inst;
}
#endif
void determine_filter_type(const char *filter_string, enum loader_filter_string_type *filter_type, const char **new_start,
size_t *new_length) { … }
VkResult parse_generic_filter_environment_var(const struct loader_instance *inst, const char *env_var_name,
struct loader_envvar_filter *filter_struct) { … }
VkResult parse_layers_disable_filter_environment_var(const struct loader_instance *inst,
struct loader_envvar_disable_layers_filter *disable_struct) { … }
VkResult parse_layer_environment_var_filters(const struct loader_instance *inst, struct loader_envvar_all_filters *layer_filters) { … }
bool check_name_matches_filter_environment_var(const char *name, const struct loader_envvar_filter *filter_struct) { … }
VkResult loader_add_environment_layers(struct loader_instance *inst, const enum layer_type_flags type_flags,
const struct loader_envvar_all_filters *filters,
struct loader_pointer_layer_list *target_list,
struct loader_pointer_layer_list *expanded_target_list,
const struct loader_layer_list *source_list) { … }