From c84388ee4c66bcd310db57489eac4a75fc600747 Mon Sep 17 00:00:00 2001 From: David Ruth Date: Tue, 4 Apr 2023 23:35:35 +0000 Subject: [PATCH] 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 --- src/crypto/tls.h | 6 +++++ src/crypto/tls_openssl.c | 30 ++++++++++++++++++++----- src/eap_peer/eap.c | 6 +++++ src/eapol_supp/eapol_supp_sm.c | 6 +++++ src/eapol_supp/eapol_supp_sm.h | 6 +++++ wpa_supplicant/Makefile | 28 +++++++++++++++++++++++ wpa_supplicant/config.c | 16 +++++++++++++ wpa_supplicant/config.h | 6 +++++ wpa_supplicant/config_file.c | 6 +++++ wpa_supplicant/dbus/dbus_new_handlers.c | 13 +++++++++++ wpa_supplicant/defconfig | 16 +++++++++++++ wpa_supplicant/wpa_supplicant.c | 6 ++++- wpa_supplicant/wpas_glue.c | 6 +++++ 13 files changed, 144 insertions(+), 7 deletions(-) diff --git a/src/crypto/tls.h b/src/crypto/tls.h index 7bed1830a..f839f9dfb 100644 --- a/src/crypto/tls.h +++ b/src/crypto/tls.h @@ -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; diff --git a/src/crypto/tls_openssl.c b/src/crypto/tls_openssl.c index fe38fa754..619785224 100644 --- a/src/crypto/tls_openssl.c +++ b/src/crypto/tls_openssl.c @@ -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; } diff --git a/src/eap_peer/eap.c b/src/eap_peer/eap.c index c8e514ab8..199ea0aab 100644 --- a/src/eap_peer/eap.c +++ b/src/eap_peer/eap.c @@ -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; diff --git a/src/eapol_supp/eapol_supp_sm.c b/src/eapol_supp/eapol_supp_sm.c index 0bfe3c970..abc1416a3 100644 --- a/src/eapol_supp/eapol_supp_sm.c +++ b/src/eapol_supp/eapol_supp_sm.c @@ -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; diff --git a/src/eapol_supp/eapol_supp_sm.h b/src/eapol_supp/eapol_supp_sm.h index 2b1aeff88..870ba1d02 100644 --- a/src/eapol_supp/eapol_supp_sm.h +++ b/src/eapol_supp/eapol_supp_sm.h @@ -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 diff --git a/wpa_supplicant/Makefile b/wpa_supplicant/Makefile index 57620fe79..8adbc3b41 100644 --- a/wpa_supplicant/Makefile +++ b/wpa_supplicant/Makefile @@ -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) diff --git a/wpa_supplicant/config.c b/wpa_supplicant/config.c index a554b7b5c..77467f00a 100644 --- a/wpa_supplicant/config.c +++ b/wpa_supplicant/config.c @@ -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 }, diff --git a/wpa_supplicant/config.h b/wpa_supplicant/config.h index 4886fe649..7d2b57028 100644 --- a/wpa_supplicant/config.h +++ b/wpa_supplicant/config.h @@ -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 diff --git a/wpa_supplicant/config_file.c b/wpa_supplicant/config_file.c index 88370e88d..9a474bd83 100644 --- a/wpa_supplicant/config_file.c +++ b/wpa_supplicant/config_file.c @@ -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) diff --git a/wpa_supplicant/dbus/dbus_new_handlers.c b/wpa_supplicant/dbus/dbus_new_handlers.c index f9c59a182..6ad49a136 100644 --- a/wpa_supplicant/dbus/dbus_new_handlers.c +++ b/wpa_supplicant/dbus/dbus_new_handlers.c @@ -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 */ } diff --git a/wpa_supplicant/defconfig b/wpa_supplicant/defconfig index 01caa8a28..8422a095f 100644 --- a/wpa_supplicant/defconfig +++ b/wpa_supplicant/defconfig @@ -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 diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c index 24f41c9ba..b75c0ec15 100644 --- a/wpa_supplicant/wpa_supplicant.c +++ b/wpa_supplicant/wpa_supplicant.c @@ -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); diff --git a/wpa_supplicant/wpas_glue.c b/wpa_supplicant/wpas_glue.c index 1d9ad4ba4..55d996d5c 100644 --- a/wpa_supplicant/wpas_glue.c +++ b/wpa_supplicant/wpas_glue.c @@ -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;