Files
bengris32 5ac30e097f libwifi-hal-wrapper: Do not close wifi hal lib on cleanup
* Freeing the fln struct and dlclosing the wifi hal library
  can cause a use-after-free if another thread is still
  using it. When a process exits, all its handles on
  any open shared libraries are closed, so there is
  no need to do it in cleanup.

Change-Id: Ib97949af6a8d3c6be8571fef7f84c0f7a65e4cca
Signed-off-by: bengris32 <bengris32@protonmail.ch>
2024-05-19 17:56:30 +01:00

204 lines
9.3 KiB
C++

/*
* SPDX-FileCopyrightText: 2024 The LineageOS Project
*
* SPDX-License-Identifier: Apache-2.0
*/
#define LOG_TAG "libwifi-hal-wrapper"
#include <dlfcn.h>
#include <stdlib.h>
#include <unistd.h>
#include <log/log.h>
#include "wifi_hal_legacy.h"
#define WIFI_HAL_LIB_NAME "libwifi-hal-mtk.so"
#define WIFI_HAL_INIT_FUNC_NAME "init_wifi_vendor_hal_func_table"
#define SET_IF_NOT_NULL(fn_ptr, fln_ptr, member) \
do { \
if ((fln_ptr) && (fln_ptr)->member) { \
(fn_ptr)->member = (fln_ptr)->member; \
} \
} while (0)
static wifi_hal_legacy_fn* fln = nullptr;
static void* lib_handle = nullptr;
wifi_error init_wifi_vendor_hal_func_table(wifi_hal_fn* fn) {
init_wifi_vendor_hal_func_table_legacy_t init_fn;
wifi_error ret = WIFI_ERROR_NONE;
fln = (wifi_hal_legacy_fn*)calloc(1, sizeof(wifi_hal_legacy_fn));
if (!fln) {
ret = WIFI_ERROR_OUT_OF_MEMORY;
goto out;
}
lib_handle = dlopen(WIFI_HAL_LIB_NAME, RTLD_LAZY);
if (!lib_handle) {
ALOGE("Failed to open vendor library %s.", WIFI_HAL_LIB_NAME);
ret = WIFI_ERROR_UNKNOWN;
goto error;
}
init_fn = (init_wifi_vendor_hal_func_table_legacy_t)dlsym(lib_handle, WIFI_HAL_INIT_FUNC_NAME);
if (!init_fn) {
ALOGE("Failed to locate vendor HAL init function.");
ret = WIFI_ERROR_UNKNOWN;
goto error;
}
ret = init_fn(fln);
if (ret != WIFI_ERROR_NONE) {
ALOGE("Vendor HAL init function returns %d.", ret);
goto error;
}
SET_IF_NOT_NULL(fn, fln, wifi_initialize);
SET_IF_NOT_NULL(fn, fln, wifi_wait_for_driver_ready);
SET_IF_NOT_NULL(fn, fln, wifi_cleanup);
SET_IF_NOT_NULL(fn, fln, wifi_event_loop);
SET_IF_NOT_NULL(fn, fln, wifi_get_error_info);
SET_IF_NOT_NULL(fn, fln, wifi_get_supported_feature_set);
SET_IF_NOT_NULL(fn, fln, wifi_get_concurrency_matrix);
SET_IF_NOT_NULL(fn, fln, wifi_set_scanning_mac_oui);
SET_IF_NOT_NULL(fn, fln, wifi_get_supported_channels);
SET_IF_NOT_NULL(fn, fln, wifi_is_epr_supported);
SET_IF_NOT_NULL(fn, fln, wifi_get_ifaces);
SET_IF_NOT_NULL(fn, fln, wifi_get_iface_name);
SET_IF_NOT_NULL(fn, fln, wifi_set_iface_event_handler);
SET_IF_NOT_NULL(fn, fln, wifi_reset_iface_event_handler);
SET_IF_NOT_NULL(fn, fln, wifi_start_gscan);
SET_IF_NOT_NULL(fn, fln, wifi_stop_gscan);
SET_IF_NOT_NULL(fn, fln, wifi_get_cached_gscan_results);
SET_IF_NOT_NULL(fn, fln, wifi_set_bssid_hotlist);
SET_IF_NOT_NULL(fn, fln, wifi_reset_bssid_hotlist);
SET_IF_NOT_NULL(fn, fln, wifi_set_significant_change_handler);
SET_IF_NOT_NULL(fn, fln, wifi_reset_significant_change_handler);
SET_IF_NOT_NULL(fn, fln, wifi_get_gscan_capabilities);
SET_IF_NOT_NULL(fn, fln, wifi_set_link_stats);
SET_IF_NOT_NULL(fn, fln, wifi_get_link_stats);
SET_IF_NOT_NULL(fn, fln, wifi_clear_link_stats);
SET_IF_NOT_NULL(fn, fln, wifi_get_valid_channels);
SET_IF_NOT_NULL(fn, fln, wifi_rtt_range_request);
SET_IF_NOT_NULL(fn, fln, wifi_rtt_range_cancel);
SET_IF_NOT_NULL(fn, fln, wifi_get_rtt_capabilities);
SET_IF_NOT_NULL(fn, fln, wifi_rtt_get_responder_info);
SET_IF_NOT_NULL(fn, fln, wifi_enable_responder);
SET_IF_NOT_NULL(fn, fln, wifi_disable_responder);
SET_IF_NOT_NULL(fn, fln, wifi_set_nodfs_flag);
SET_IF_NOT_NULL(fn, fln, wifi_start_logging);
SET_IF_NOT_NULL(fn, fln, wifi_set_epno_list);
SET_IF_NOT_NULL(fn, fln, wifi_reset_epno_list);
SET_IF_NOT_NULL(fn, fln, wifi_set_country_code);
SET_IF_NOT_NULL(fn, fln, wifi_get_firmware_memory_dump);
SET_IF_NOT_NULL(fn, fln, wifi_set_log_handler);
SET_IF_NOT_NULL(fn, fln, wifi_reset_log_handler);
SET_IF_NOT_NULL(fn, fln, wifi_set_alert_handler);
SET_IF_NOT_NULL(fn, fln, wifi_reset_alert_handler);
SET_IF_NOT_NULL(fn, fln, wifi_get_firmware_version);
SET_IF_NOT_NULL(fn, fln, wifi_get_ring_buffers_status);
SET_IF_NOT_NULL(fn, fln, wifi_get_logger_supported_feature_set);
SET_IF_NOT_NULL(fn, fln, wifi_get_ring_data);
SET_IF_NOT_NULL(fn, fln, wifi_enable_tdls);
SET_IF_NOT_NULL(fn, fln, wifi_disable_tdls);
SET_IF_NOT_NULL(fn, fln, wifi_get_tdls_status);
SET_IF_NOT_NULL(fn, fln, wifi_get_tdls_capabilities);
SET_IF_NOT_NULL(fn, fln, wifi_get_driver_version);
SET_IF_NOT_NULL(fn, fln, wifi_set_passpoint_list);
SET_IF_NOT_NULL(fn, fln, wifi_reset_passpoint_list);
SET_IF_NOT_NULL(fn, fln, wifi_set_lci);
SET_IF_NOT_NULL(fn, fln, wifi_set_lcr);
SET_IF_NOT_NULL(fn, fln, wifi_start_sending_offloaded_packet);
SET_IF_NOT_NULL(fn, fln, wifi_stop_sending_offloaded_packet);
SET_IF_NOT_NULL(fn, fln, wifi_start_rssi_monitoring);
SET_IF_NOT_NULL(fn, fln, wifi_stop_rssi_monitoring);
SET_IF_NOT_NULL(fn, fln, wifi_get_wake_reason_stats);
SET_IF_NOT_NULL(fn, fln, wifi_configure_nd_offload);
SET_IF_NOT_NULL(fn, fln, wifi_get_driver_memory_dump);
SET_IF_NOT_NULL(fn, fln, wifi_start_pkt_fate_monitoring);
SET_IF_NOT_NULL(fn, fln, wifi_get_tx_pkt_fates);
SET_IF_NOT_NULL(fn, fln, wifi_get_rx_pkt_fates);
SET_IF_NOT_NULL(fn, fln, wifi_nan_enable_request);
SET_IF_NOT_NULL(fn, fln, wifi_nan_disable_request);
SET_IF_NOT_NULL(fn, fln, wifi_nan_publish_request);
SET_IF_NOT_NULL(fn, fln, wifi_nan_publish_cancel_request);
SET_IF_NOT_NULL(fn, fln, wifi_nan_subscribe_request);
SET_IF_NOT_NULL(fn, fln, wifi_nan_subscribe_cancel_request);
SET_IF_NOT_NULL(fn, fln, wifi_nan_transmit_followup_request);
SET_IF_NOT_NULL(fn, fln, wifi_nan_stats_request);
SET_IF_NOT_NULL(fn, fln, wifi_nan_config_request);
SET_IF_NOT_NULL(fn, fln, wifi_nan_tca_request);
SET_IF_NOT_NULL(fn, fln, wifi_nan_beacon_sdf_payload_request);
SET_IF_NOT_NULL(fn, fln, wifi_nan_register_handler);
SET_IF_NOT_NULL(fn, fln, wifi_nan_get_version);
SET_IF_NOT_NULL(fn, fln, wifi_nan_get_capabilities);
SET_IF_NOT_NULL(fn, fln, wifi_nan_data_interface_create);
SET_IF_NOT_NULL(fn, fln, wifi_nan_data_interface_delete);
SET_IF_NOT_NULL(fn, fln, wifi_nan_data_request_initiator);
SET_IF_NOT_NULL(fn, fln, wifi_nan_data_indication_response);
SET_IF_NOT_NULL(fn, fln, wifi_nan_pairing_request);
SET_IF_NOT_NULL(fn, fln, wifi_nan_pairing_indication_response);
SET_IF_NOT_NULL(fn, fln, wifi_nan_bootstrapping_request);
SET_IF_NOT_NULL(fn, fln, wifi_nan_bootstrapping_indication_response);
SET_IF_NOT_NULL(fn, fln, wifi_nan_data_end);
SET_IF_NOT_NULL(fn, fln, wifi_nan_pairing_end);
SET_IF_NOT_NULL(fn, fln, wifi_get_packet_filter_capabilities);
SET_IF_NOT_NULL(fn, fln, wifi_set_packet_filter);
SET_IF_NOT_NULL(fn, fln, wifi_read_packet_filter);
SET_IF_NOT_NULL(fn, fln, wifi_get_roaming_capabilities);
SET_IF_NOT_NULL(fn, fln, wifi_enable_firmware_roaming);
SET_IF_NOT_NULL(fn, fln, wifi_configure_roaming);
SET_IF_NOT_NULL(fn, fln, wifi_select_tx_power_scenario);
SET_IF_NOT_NULL(fn, fln, wifi_reset_tx_power_scenario);
SET_IF_NOT_NULL(fn, fln, wifi_set_radio_mode_change_handler);
SET_IF_NOT_NULL(fn, fln, wifi_set_latency_mode);
SET_IF_NOT_NULL(fn, fln, wifi_set_thermal_mitigation_mode);
SET_IF_NOT_NULL(fn, fln, wifi_virtual_interface_create);
SET_IF_NOT_NULL(fn, fln, wifi_virtual_interface_delete);
SET_IF_NOT_NULL(fn, fln, wifi_map_dscp_access_category);
SET_IF_NOT_NULL(fn, fln, wifi_reset_dscp_mapping);
SET_IF_NOT_NULL(fn, fln, wifi_set_subsystem_restart_handler);
SET_IF_NOT_NULL(fn, fln, wifi_get_supported_iface_name);
SET_IF_NOT_NULL(fn, fln, wifi_early_initialize);
SET_IF_NOT_NULL(fn, fln, wifi_get_chip_feature_set);
SET_IF_NOT_NULL(fn, fln, wifi_multi_sta_set_primary_connection);
SET_IF_NOT_NULL(fn, fln, wifi_multi_sta_set_use_case);
SET_IF_NOT_NULL(fn, fln, wifi_set_coex_unsafe_channels);
SET_IF_NOT_NULL(fn, fln, wifi_set_voip_mode);
SET_IF_NOT_NULL(fn, fln, wifi_twt_register_handler);
SET_IF_NOT_NULL(fn, fln, wifi_twt_get_capability);
SET_IF_NOT_NULL(fn, fln, wifi_twt_setup_request);
SET_IF_NOT_NULL(fn, fln, wifi_twt_teardown_request);
SET_IF_NOT_NULL(fn, fln, wifi_twt_info_frame_request);
SET_IF_NOT_NULL(fn, fln, wifi_twt_get_stats);
SET_IF_NOT_NULL(fn, fln, wifi_twt_clear_stats);
SET_IF_NOT_NULL(fn, fln, wifi_set_dtim_config);
SET_IF_NOT_NULL(fn, fln, wifi_get_usable_channels);
SET_IF_NOT_NULL(fn, fln, wifi_trigger_subsystem_restart);
SET_IF_NOT_NULL(fn, fln, wifi_set_indoor_state);
SET_IF_NOT_NULL(fn, fln, wifi_get_supported_radio_combinations_matrix);
SET_IF_NOT_NULL(fn, fln, wifi_nan_rtt_chre_enable_request);
SET_IF_NOT_NULL(fn, fln, wifi_nan_rtt_chre_disable_request);
SET_IF_NOT_NULL(fn, fln, wifi_chre_register_handler);
SET_IF_NOT_NULL(fn, fln, wifi_enable_tx_power_limits);
SET_IF_NOT_NULL(fn, fln, wifi_get_cached_scan_results);
SET_IF_NOT_NULL(fn, fln, wifi_get_chip_capabilities);
SET_IF_NOT_NULL(fn, fln, wifi_enable_sta_channel_for_peer_network);
SET_IF_NOT_NULL(fn, fln, wifi_nan_suspend_request);
SET_IF_NOT_NULL(fn, fln, wifi_nan_resume_request);
SET_IF_NOT_NULL(fn, fln, wifi_set_scan_mode);
SET_IF_NOT_NULL(fn, fln, wifi_set_mlo_mode);
SET_IF_NOT_NULL(fn, fln, wifi_get_supported_iface_concurrency_matrix);
out:
return ret;
error:
free(fln);
if (lib_handle) dlclose(lib_handle);
return ret;
}