Compile-time config for dynamically loading libraries in wpa_supplicant

Prevent loading arbitrary executable code based on config at runtime,
while allowing libraries to be specified at compile time when they are
known in advance.

Add the ability to configure libraries to load at compile time.
	* CONFIG_PKCS11_ENGINE_PATH - pkcs11_engine library location.
	* CONFIG_PKCS11_MODULE_PATH - pkcs11_module library location.
	* CONFIG_OPENSC_ENGINE_PATH - opensc_engine library location.

Add flags with the ability to set each of the libraries to NULL and
prevent loading them at runtime.
	* CONFIG_NO_PKCS11_ENGINE_PATH - prevents loading pkcs11_engine
	  library.
	* CONFIG_NO_PKCS11_MODULE_PATH - prevents loading pkcs11_module
	  library.
	* CONFIG_NO_OPENSC_ENGINE_PATH - prevents loading opensc_engine
	  library.
	* CONFIG_NO_LOAD_DYNAMIC_EAP - prevents loading EAP libraries at
	  runtime.

Signed-off-by: David Ruth <druth@chromium.org>
This commit is contained in:
David Ruth 2023-04-04 23:35:35 +00:00 committed by Jouni Malinen
parent 890953a32c
commit c84388ee4c
13 changed files with 144 additions and 7 deletions

View file

@ -80,9 +80,15 @@ union tls_event_data {
};
struct tls_config {
#ifndef CONFIG_OPENSC_ENGINE_PATH
const char *opensc_engine_path;
#endif /* CONFIG_OPENSC_ENGINE_PATH */
#ifndef CONFIG_PKCS11_ENGINE_PATH
const char *pkcs11_engine_path;
#endif /* CONFIG_PKCS11_ENGINE_PATH */
#ifndef CONFIG_PKCS11_MODULE_PATH
const char *pkcs11_module_path;
#endif /* CONFIG_PKCS11_MODULE_PATH */
int fips_mode;
int cert_in_cb;
const char *openssl_ciphers;

View file

@ -992,6 +992,26 @@ void * tls_init(const struct tls_config *conf)
SSL_CTX *ssl;
struct tls_context *context;
const char *ciphers;
#ifndef OPENSSL_NO_ENGINE
#ifdef CONFIG_OPENSC_ENGINE_PATH
char const * const opensc_engine_path = CONFIG_OPENSC_ENGINE_PATH;
#else /* CONFIG_OPENSC_ENGINE_PATH */
char const * const opensc_engine_path =
conf ? conf->opensc_engine_path : NULL;
#endif /* CONFIG_OPENSC_ENGINE_PATH */
#ifdef CONFIG_PKCS11_ENGINE_PATH
char const * const pkcs11_engine_path = CONFIG_PKCS11_ENGINE_PATH;
#else /* CONFIG_PKCS11_ENGINE_PATH */
char const * const pkcs11_engine_path =
conf ? conf->pkcs11_engine_path : NULL;
#endif /* CONFIG_PKCS11_ENGINE_PATH */
#ifdef CONFIG_PKCS11_MODULE_PATH
char const * const pkcs11_module_path = CONFIG_PKCS11_MODULE_PATH;
#else /* CONFIG_PKCS11_MODULE_PATH */
char const * const pkcs11_module_path =
conf ? conf->pkcs11_module_path : NULL;
#endif /* CONFIG_PKCS11_MODULE_PATH */
#endif /* OPENSSL_NO_ENGINE */
if (tls_openssl_ref_count == 0) {
void openssl_load_legacy_provider(void);
@ -1134,12 +1154,10 @@ void * tls_init(const struct tls_config *conf)
wpa_printf(MSG_DEBUG, "ENGINE: Loading builtin engines");
ENGINE_load_builtin_engines();
if (conf &&
(conf->opensc_engine_path || conf->pkcs11_engine_path ||
conf->pkcs11_module_path)) {
if (tls_engine_load_dynamic_opensc(conf->opensc_engine_path) ||
tls_engine_load_dynamic_pkcs11(conf->pkcs11_engine_path,
conf->pkcs11_module_path)) {
if (opensc_engine_path || pkcs11_engine_path || pkcs11_module_path) {
if (tls_engine_load_dynamic_opensc(opensc_engine_path) ||
tls_engine_load_dynamic_pkcs11(pkcs11_engine_path,
pkcs11_module_path)) {
tls_deinit(data);
return NULL;
}

View file

@ -2220,9 +2220,15 @@ struct eap_sm * eap_peer_sm_init(void *eapol_ctx,
dl_list_init(&sm->erp_keys);
os_memset(&tlsconf, 0, sizeof(tlsconf));
#ifndef CONFIG_OPENSC_ENGINE_PATH
tlsconf.opensc_engine_path = conf->opensc_engine_path;
#endif /* CONFIG_OPENSC_ENGINE_PATH */
#ifndef CONFIG_PKCS11_ENGINE_PATH
tlsconf.pkcs11_engine_path = conf->pkcs11_engine_path;
#endif /* CONFIG_PKCS11_ENGINE_PATH */
#ifndef CONFIG_PKCS11_MODULE_PATH
tlsconf.pkcs11_module_path = conf->pkcs11_module_path;
#endif /* CONFIG_PKCS11_MODULE_PATH */
tlsconf.openssl_ciphers = conf->openssl_ciphers;
#ifdef CONFIG_FIPS
tlsconf.fips_mode = 1;

View file

@ -2136,9 +2136,15 @@ struct eapol_sm *eapol_sm_init(struct eapol_ctx *ctx)
sm->authPeriod = 30;
os_memset(&conf, 0, sizeof(conf));
#ifndef CONFIG_OPENSC_ENGINE_PATH
conf.opensc_engine_path = ctx->opensc_engine_path;
#endif /* CONFIG_OPENSC_ENGINE_PATH */
#ifndef CONFIG_PKCS11_ENGINE_PATH
conf.pkcs11_engine_path = ctx->pkcs11_engine_path;
#endif /* CONFIG_PKCS11_ENGINE_PATH */
#ifndef CONFIG_PKCS11_MODULE_PATH
conf.pkcs11_module_path = ctx->pkcs11_module_path;
#endif /* CONFIG_PKCS11_MODULE_PATH */
conf.openssl_ciphers = ctx->openssl_ciphers;
conf.wps = ctx->wps;
conf.cert_in_cb = ctx->cert_in_cb;

View file

@ -188,6 +188,7 @@ struct eapol_ctx {
*/
void (*aborted_cached)(void *ctx);
#ifndef CONFIG_OPENSC_ENGINE_PATH
/**
* opensc_engine_path - Path to the OpenSSL engine for opensc
*
@ -195,7 +196,9 @@ struct eapol_ctx {
* engine (engine_opensc.so); if %NULL, this engine is not loaded.
*/
const char *opensc_engine_path;
#endif /* CONFIG_OPENSC_ENGINE_PATH */
#ifndef CONFIG_PKCS11_ENGINE_PATH
/**
* pkcs11_engine_path - Path to the OpenSSL engine for PKCS#11
*
@ -203,7 +206,9 @@ struct eapol_ctx {
* engine (engine_pkcs11.so); if %NULL, this engine is not loaded.
*/
const char *pkcs11_engine_path;
#endif /* CONFIG_PKCS11_ENGINE_PATH */
#ifndef CONFIG_PKCS11_MODULE_PATH
/**
* pkcs11_module_path - Path to the OpenSSL OpenSC/PKCS#11 module
*
@ -212,6 +217,7 @@ struct eapol_ctx {
* module is not loaded.
*/
const char *pkcs11_module_path;
#endif /* CONFIG_PKCS11_MODULE_PATH */
/**
* openssl_ciphers - OpenSSL cipher string

View file

@ -445,6 +445,34 @@ ifdef CONFIG_NO_ROAMING
CFLAGS += -DCONFIG_NO_ROAMING
endif
ifdef CONFIG_OPENSC_ENGINE_PATH
CFLAGS += -DCONFIG_OPENSC_ENGINE_PATH=\"$(CONFIG_OPENSC_ENGINE_PATH)\"
endif
ifdef CONFIG_NO_OPENSC_ENGINE_PATH
CFLAGS += -DCONFIG_OPENSC_ENGINE_PATH=NULL
endif
ifdef CONFIG_PKCS11_ENGINE_PATH
CFLAGS += -DCONFIG_PKCS11_ENGINE_PATH=\"$(CONFIG_PKCS11_ENGINE_PATH)\"
endif
ifdef CONFIG_NO_PKCS11_ENGINE_PATH
CFLAGS += -DCONFIG_PKCS11_ENGINE_PATH=NULL
endif
ifdef CONFIG_PKCS11_MODULE_PATH
CFLAGS += -DCONFIG_PKCS11_MODULE_PATH=\"$(CONFIG_PKCS11_MODULE_PATH)\"
endif
ifdef CONFIG_NO_PKCS11_MODULE_PATH
CFLAGS += -DCONFIG_PKCS11_MODULE_PATH=NULL
endif
ifdef CONFIG_NO_LOAD_DYNAMIC_EAP
CFLAGS += -DCONFIG_NO_LOAD_DYNAMIC_EAP
endif
include ../src/drivers/drivers.mak
ifdef CONFIG_AP
OBJS_d += $(DRV_BOTH_OBJS)

View file

@ -3023,9 +3023,15 @@ void wpa_config_free(struct wpa_config *config)
wpabuf_free(config->wps_vendor_ext[i]);
os_free(config->ctrl_interface);
os_free(config->ctrl_interface_group);
#ifndef CONFIG_OPENSC_ENGINE_PATH
os_free(config->opensc_engine_path);
#endif /* CONFIG_OPENSC_ENGINE_PATH */
#ifndef CONFIG_PKCS11_ENGINE_PATH
os_free(config->pkcs11_engine_path);
#endif /* CONFIG_PKCS11_ENGINE_PATH */
#ifndef CONFIG_PKCS11_MODULE_PATH
os_free(config->pkcs11_module_path);
#endif /* CONFIG_PKCS11_MODULE_PATH */
os_free(config->openssl_ciphers);
os_free(config->pcsc_reader);
str_clear_free(config->pcsc_pin);
@ -4939,6 +4945,7 @@ static int wpa_config_process_country(const struct global_parse_data *data,
}
#ifndef CONFIG_NO_LOAD_DYNAMIC_EAP
static int wpa_config_process_load_dynamic_eap(
const struct global_parse_data *data, struct wpa_config *config,
int line, const char *so)
@ -4957,6 +4964,7 @@ static int wpa_config_process_load_dynamic_eap(
return 0;
}
#endif /* CONFIG_NO_LOAD_DYNAMIC_EAP */
#ifdef CONFIG_WPS
@ -5338,9 +5346,15 @@ static const struct global_parse_data global_fields[] = {
#endif /* CONFIG_MESH */
{ INT(disable_scan_offload), 0 },
{ INT(fast_reauth), 0 },
#ifndef CONFIG_OPENSC_ENGINE_PATH
{ STR(opensc_engine_path), 0 },
#endif /* CONFIG_OPENSC_ENGINE_PATH */
#ifndef CONFIG_PKCS11_ENGINE_PATH
{ STR(pkcs11_engine_path), 0 },
#endif /* CONFIG_PKCS11_ENGINE_PATH */
#ifndef CONFIG_PKCS11_MODULE_PATH
{ STR(pkcs11_module_path), 0 },
#endif /* CONFIG_PKCS11_MODULE_PATH */
{ STR(openssl_ciphers), 0 },
{ STR(pcsc_reader), 0 },
{ STR(pcsc_pin), 0 },
@ -5352,7 +5366,9 @@ static const struct global_parse_data global_fields[] = {
#ifndef CONFIG_NO_CONFIG_WRITE
{ INT(update_config), 0 },
#endif /* CONFIG_NO_CONFIG_WRITE */
#ifndef CONFIG_NO_LOAD_DYNAMIC_EAP
{ FUNC_NO_VAR(load_dynamic_eap), 0 },
#endif /* CONFIG_NO_LOAD_DYNAMIC_EAP */
#ifdef CONFIG_WPS
{ FUNC(uuid), CFG_CHANGED_UUID },
{ INT_RANGE(auto_uuid, 0, 1), 0 },

View file

@ -615,6 +615,7 @@ struct wpa_config {
*/
int fast_reauth;
#ifndef CONFIG_OPENSC_ENGINE_PATH
/**
* opensc_engine_path - Path to the OpenSSL engine for opensc
*
@ -622,7 +623,9 @@ struct wpa_config {
* engine (engine_opensc.so); if %NULL, this engine is not loaded.
*/
char *opensc_engine_path;
#endif /* CONFIG_OPENSC_ENGINE_PATH */
#ifndef CONFIG_PKCS11_ENGINE_PATH
/**
* pkcs11_engine_path - Path to the OpenSSL engine for PKCS#11
*
@ -630,7 +633,9 @@ struct wpa_config {
* engine (engine_pkcs11.so); if %NULL, this engine is not loaded.
*/
char *pkcs11_engine_path;
#endif /* CONFIG_PKCS11_ENGINE_PATH */
#ifndef CONFIG_PKCS11_MODULE_PATH
/**
* pkcs11_module_path - Path to the OpenSSL OpenSC/PKCS#11 module
*
@ -639,6 +644,7 @@ struct wpa_config {
* module is not loaded.
*/
char *pkcs11_module_path;
#endif /* CONFIG_PKCS11_MODULE_PATH */
/**
* openssl_ciphers - OpenSSL cipher string

View file

@ -1124,15 +1124,21 @@ static void wpa_config_write_global(FILE *f, struct wpa_config *config)
config->disable_scan_offload);
if (config->fast_reauth != DEFAULT_FAST_REAUTH)
fprintf(f, "fast_reauth=%d\n", config->fast_reauth);
#ifndef CONFIG_OPENSC_ENGINE_PATH
if (config->opensc_engine_path)
fprintf(f, "opensc_engine_path=%s\n",
config->opensc_engine_path);
#endif /* CONFIG_OPENSC_ENGINE_PATH */
#ifndef CONFIG_PKCS11_ENGINE_PATH
if (config->pkcs11_engine_path)
fprintf(f, "pkcs11_engine_path=%s\n",
config->pkcs11_engine_path);
#endif /* CONFIG_PKCS11_ENGINE_PATH */
#ifndef CONFIG_PKCS11_MODULE_PATH
if (config->pkcs11_module_path)
fprintf(f, "pkcs11_module_path=%s\n",
config->pkcs11_module_path);
#endif /* CONFIG_PKCS11_MODULE_PATH */
if (config->openssl_ciphers)
fprintf(f, "openssl_ciphers=%s\n", config->openssl_ciphers);
if (config->pcsc_reader)

View file

@ -4343,11 +4343,18 @@ dbus_bool_t wpas_dbus_getter_pkcs11_engine_path(
const struct wpa_dbus_property_desc *property_desc,
DBusMessageIter *iter, DBusError *error, void *user_data)
{
#ifndef CONFIG_PKCS11_ENGINE_PATH
struct wpa_supplicant *wpa_s = user_data;
return wpas_dbus_string_property_getter(iter,
wpa_s->conf->pkcs11_engine_path,
error);
#else /* CONFIG_PKCS11_ENGINE_PATH */
return wpas_dbus_string_property_getter(iter,
CONFIG_PKCS11_ENGINE_PATH,
error);
#endif /* CONFIG_PKCS11_ENGINE_PATH */
}
@ -4364,11 +4371,17 @@ dbus_bool_t wpas_dbus_getter_pkcs11_module_path(
const struct wpa_dbus_property_desc *property_desc,
DBusMessageIter *iter, DBusError *error, void *user_data)
{
#ifndef CONFIG_PKCS11_MODULE_PATH
struct wpa_supplicant *wpa_s = user_data;
return wpas_dbus_string_property_getter(iter,
wpa_s->conf->pkcs11_module_path,
error);
#else /* CONFIG_PKCS11_MODULE_PATH */
return wpas_dbus_string_property_getter(iter,
CONFIG_PKCS11_MODULE_PATH,
error);
#endif /* CONFIG_PKCS11_MODULE_PATH */
}

View file

@ -401,6 +401,22 @@ CONFIG_CTRL_IFACE_DBUS_INTRO=y
# amount of memory/flash.
#CONFIG_DYNAMIC_EAP_METHODS=y
# Dynamic library loading
# Add the ability to configure libraries to load at compile time.
# If set, these disable dynamic configuration.
#CONFIG_PKCS11_ENGINE_PATH - pkcs11_engine library location.
#CONFIG_PKCS11_MODULE_PATH - pkcs11_module library location.
#CONFIG_OPENSC_ENGINE_PATH - opensc_engine library location.
#
# Prevent library loading at runtime
#CONFIG_NO_PKCS11_ENGINE_PATH=y # prevents loading pkcs11_engine library.
#CONFIG_NO_PKCS11_MODULE_PATH=y # prevents loading pkcs11_module library.
# CONFIG_NO_OPENSC_ENGINE_PATH=y # prevents loading opensc_engine library.
# Prevents loading EAP libraries at runtime
#CONFIG_NO_LOAD_DYNAMIC_EAP=y
# IEEE Std 802.11r-2008 (Fast BSS Transition) for station mode
CONFIG_IEEE80211R=y

View file

@ -5017,10 +5017,14 @@ int wpas_set_pkcs11_engine_and_module_path(struct wpa_supplicant *wpa_s,
}
}
#ifndef CONFIG_PKCS11_ENGINE_PATH
os_free(wpa_s->conf->pkcs11_engine_path);
os_free(wpa_s->conf->pkcs11_module_path);
wpa_s->conf->pkcs11_engine_path = pkcs11_engine_path_copy;
#endif /* CONFIG_PKCS11_ENGINE_PATH */
#ifndef CONFIG_PKCS11_MODULE_PATH
os_free(wpa_s->conf->pkcs11_module_path);
wpa_s->conf->pkcs11_module_path = pkcs11_module_path_copy;
#endif /* CONFIG_PKCS11_MODULE_PATH */
wpa_sm_set_eapol(wpa_s->wpa, NULL);
eapol_sm_deinit(wpa_s->eapol);

View file

@ -1185,9 +1185,15 @@ int wpa_supplicant_init_eapol(struct wpa_supplicant *wpa_s)
ctx->get_config_blob = wpa_supplicant_get_config_blob;
#endif /* CONFIG_NO_CONFIG_BLOBS */
ctx->aborted_cached = wpa_supplicant_aborted_cached;
#ifndef CONFIG_OPENSC_ENGINE_PATH
ctx->opensc_engine_path = wpa_s->conf->opensc_engine_path;
#endif /* CONFIG_OPENSC_ENGINE_PATH */
#ifndef CONFIG_PKCS11_ENGINE_PATH
ctx->pkcs11_engine_path = wpa_s->conf->pkcs11_engine_path;
#endif /* CONFIG_PKCS11_ENGINE_PATH */
#ifndef CONFIG_PKCS11_MODULE_PATH
ctx->pkcs11_module_path = wpa_s->conf->pkcs11_module_path;
#endif /* CONFIG_PKCS11_MODULE_PATH */
ctx->openssl_ciphers = wpa_s->conf->openssl_ciphers;
ctx->wps = wpa_s->wps;
ctx->eap_param_needed = wpa_supplicant_eap_param_needed;