fix some issues with P2P operation
This commit is contained in:
parent
e119134a59
commit
bc38aa032d
209
0001-D-Bus-Fix-P2P-NULL-dereference-after-interface-remov.patch
Normal file
209
0001-D-Bus-Fix-P2P-NULL-dereference-after-interface-remov.patch
Normal file
@ -0,0 +1,209 @@
|
||||
From b2ad4e6b24ed0271ca76cb27856def0a701fb778 Mon Sep 17 00:00:00 2001
|
||||
From: Davide Caratti <davide.caratti@gmail.com>
|
||||
Date: Wed, 2 Oct 2019 14:08:41 +0200
|
||||
Subject: [PATCH] D-Bus: Fix P2P NULL dereference after interface removal
|
||||
|
||||
When the P2P management interface is deleted, P2P is then disabled and
|
||||
global->p2p_init_wpa_s is set to NULL. After that, other interfaces can
|
||||
still trigger P2P functions (like wpas_p2p_find()) using D-Bus. This
|
||||
makes wpa_supplicant terminate with SIGSEGV, because it dereferences a
|
||||
NULL pointer. Fix this by adding proper checks, like it's done with
|
||||
wpa_cli.
|
||||
|
||||
CC: Beniamino Galvani <bgalvani@redhat.com>
|
||||
CC: Benjamin Berg <benjamin@sipsolutions.net>
|
||||
Reported-by: Vladimir Benes <vbenes@redhat.com>
|
||||
Signed-off-by: Davide Caratti <davide.caratti@gmail.com>
|
||||
---
|
||||
wpa_supplicant/dbus/dbus_new_handlers_p2p.c | 69 ++++++++++++++++++++-
|
||||
1 file changed, 67 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/wpa_supplicant/dbus/dbus_new_handlers_p2p.c b/wpa_supplicant/dbus/dbus_new_handlers_p2p.c
|
||||
index 8cdd88564..19715eb4c 100644
|
||||
--- a/wpa_supplicant/dbus/dbus_new_handlers_p2p.c
|
||||
+++ b/wpa_supplicant/dbus/dbus_new_handlers_p2p.c
|
||||
@@ -40,6 +40,14 @@ static int wpas_dbus_validate_dbus_ipaddr(struct wpa_dbus_dict_entry entry)
|
||||
}
|
||||
|
||||
|
||||
+static dbus_bool_t no_p2p_mgmt_interface(DBusError *error)
|
||||
+{
|
||||
+ dbus_set_error_const(error, WPAS_DBUS_ERROR_IFACE_UNKNOWN,
|
||||
+ "Could not find P2P mgmt interface");
|
||||
+ return FALSE;
|
||||
+}
|
||||
+
|
||||
+
|
||||
/**
|
||||
* Parses out the mac address from the peer object path.
|
||||
* @peer_path - object path of the form
|
||||
@@ -78,6 +86,22 @@ wpas_dbus_error_persistent_group_unknown(DBusMessage *message)
|
||||
}
|
||||
|
||||
|
||||
+/**
|
||||
+ * wpas_dbus_error_no_p2p_mgmt_iface - Return a new InterfaceUnknown error
|
||||
+ * message
|
||||
+ * @message: Pointer to incoming dbus message this error refers to
|
||||
+ * Returns: a dbus error message
|
||||
+ *
|
||||
+ * Convenience function to create and return an unknown interface error.
|
||||
+ */
|
||||
+static DBusMessage * wpas_dbus_error_no_p2p_mgmt_iface(DBusMessage *message)
|
||||
+{
|
||||
+ wpa_printf(MSG_DEBUG, "dbus: Could not find P2P mgmt interface");
|
||||
+ return dbus_message_new_error(message, WPAS_DBUS_ERROR_IFACE_UNKNOWN,
|
||||
+ "Could not find P2P mgmt interface");
|
||||
+}
|
||||
+
|
||||
+
|
||||
DBusMessage * wpas_dbus_handler_p2p_find(DBusMessage *message,
|
||||
struct wpa_supplicant *wpa_s)
|
||||
{
|
||||
@@ -145,6 +169,10 @@ DBusMessage * wpas_dbus_handler_p2p_find(DBusMessage *message,
|
||||
}
|
||||
|
||||
wpa_s = wpa_s->global->p2p_init_wpa_s;
|
||||
+ if (!wpa_s) {
|
||||
+ reply = wpas_dbus_error_no_p2p_mgmt_iface(message);
|
||||
+ goto error_nop2p;
|
||||
+ }
|
||||
|
||||
if (wpas_p2p_find(wpa_s, timeout, type, num_req_dev_types,
|
||||
req_dev_types, NULL, 0, 0, NULL, freq))
|
||||
@@ -157,8 +185,9 @@ DBusMessage * wpas_dbus_handler_p2p_find(DBusMessage *message,
|
||||
error_clear:
|
||||
wpa_dbus_dict_entry_clear(&entry);
|
||||
error:
|
||||
- os_free(req_dev_types);
|
||||
reply = wpas_dbus_error_invalid_args(message, entry.key);
|
||||
+error_nop2p:
|
||||
+ os_free(req_dev_types);
|
||||
return reply;
|
||||
}
|
||||
|
||||
@@ -166,7 +195,9 @@ error:
|
||||
DBusMessage * wpas_dbus_handler_p2p_stop_find(DBusMessage *message,
|
||||
struct wpa_supplicant *wpa_s)
|
||||
{
|
||||
- wpas_p2p_stop_find(wpa_s->global->p2p_init_wpa_s);
|
||||
+ wpa_s = wpa_s->global->p2p_init_wpa_s;
|
||||
+ if (wpa_s)
|
||||
+ wpas_p2p_stop_find(wpa_s);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -185,6 +216,8 @@ DBusMessage * wpas_dbus_handler_p2p_rejectpeer(DBusMessage *message,
|
||||
return wpas_dbus_error_invalid_args(message, NULL);
|
||||
|
||||
wpa_s = wpa_s->global->p2p_init_wpa_s;
|
||||
+ if (!wpa_s)
|
||||
+ return wpas_dbus_error_no_p2p_mgmt_iface(message);
|
||||
|
||||
if (wpas_p2p_reject(wpa_s, peer_addr) < 0)
|
||||
return wpas_dbus_error_unknown_error(message,
|
||||
@@ -204,6 +237,8 @@ DBusMessage * wpas_dbus_handler_p2p_listen(DBusMessage *message,
|
||||
return wpas_dbus_error_no_memory(message);
|
||||
|
||||
wpa_s = wpa_s->global->p2p_init_wpa_s;
|
||||
+ if (!wpa_s)
|
||||
+ return wpas_dbus_error_no_p2p_mgmt_iface(message);
|
||||
|
||||
if (wpas_p2p_listen(wpa_s, (unsigned int) timeout)) {
|
||||
return dbus_message_new_error(message,
|
||||
@@ -245,6 +280,8 @@ DBusMessage * wpas_dbus_handler_p2p_extendedlisten(
|
||||
}
|
||||
|
||||
wpa_s = wpa_s->global->p2p_init_wpa_s;
|
||||
+ if (!wpa_s)
|
||||
+ return wpas_dbus_error_no_p2p_mgmt_iface(message);
|
||||
|
||||
if (wpas_p2p_ext_listen(wpa_s, period, interval))
|
||||
return wpas_dbus_error_unknown_error(
|
||||
@@ -350,6 +387,10 @@ DBusMessage * wpas_dbus_handler_p2p_group_add(DBusMessage *message,
|
||||
}
|
||||
|
||||
wpa_s = wpa_s->global->p2p_init_wpa_s;
|
||||
+ if (!wpa_s) {
|
||||
+ reply = wpas_dbus_error_no_p2p_mgmt_iface(message);
|
||||
+ goto out;
|
||||
+ }
|
||||
|
||||
if (pg_object_path != NULL) {
|
||||
char *net_id_str;
|
||||
@@ -433,6 +474,12 @@ static dbus_bool_t wpa_dbus_p2p_check_enabled(struct wpa_supplicant *wpa_s,
|
||||
"P2P is not available for this interface");
|
||||
return FALSE;
|
||||
}
|
||||
+ if (!wpa_s->global->p2p_init_wpa_s) {
|
||||
+ if (out_reply)
|
||||
+ *out_reply = wpas_dbus_error_no_p2p_mgmt_iface(
|
||||
+ message);
|
||||
+ return no_p2p_mgmt_interface(error);
|
||||
+ }
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -822,6 +869,8 @@ DBusMessage * wpas_dbus_handler_p2p_prov_disc_req(DBusMessage *message,
|
||||
return wpas_dbus_error_invalid_args(message, NULL);
|
||||
|
||||
wpa_s = wpa_s->global->p2p_init_wpa_s;
|
||||
+ if (!wpa_s)
|
||||
+ return wpas_dbus_error_no_p2p_mgmt_iface(message);
|
||||
|
||||
if (wpas_p2p_prov_disc(wpa_s, peer_addr, config_method,
|
||||
WPAS_P2P_PD_FOR_GO_NEG, NULL) < 0)
|
||||
@@ -1882,6 +1931,8 @@ dbus_bool_t wpas_dbus_getter_p2p_peer_groups(
|
||||
|
||||
wpa_s = peer_args->wpa_s;
|
||||
wpa_s = wpa_s->global->p2p_init_wpa_s;
|
||||
+ if (!wpa_s)
|
||||
+ return no_p2p_mgmt_interface(error);
|
||||
|
||||
wpa_s_go = wpas_get_p2p_client_iface(wpa_s, info->p2p_device_addr);
|
||||
if (wpa_s_go) {
|
||||
@@ -1963,6 +2014,9 @@ dbus_bool_t wpas_dbus_getter_persistent_groups(
|
||||
dbus_bool_t success = FALSE;
|
||||
|
||||
wpa_s = wpa_s->global->p2p_init_wpa_s;
|
||||
+ if (!wpa_s)
|
||||
+ return no_p2p_mgmt_interface(error);
|
||||
+
|
||||
if (!wpa_s->parent->dbus_new_path)
|
||||
return FALSE;
|
||||
|
||||
@@ -2077,6 +2131,11 @@ DBusMessage * wpas_dbus_handler_add_persistent_group(
|
||||
dbus_message_iter_init(message, &iter);
|
||||
|
||||
wpa_s = wpa_s->global->p2p_init_wpa_s;
|
||||
+ if (!wpa_s) {
|
||||
+ reply = wpas_dbus_error_no_p2p_mgmt_iface(message);
|
||||
+ goto err;
|
||||
+ }
|
||||
+
|
||||
if (wpa_s->parent->dbus_new_path)
|
||||
ssid = wpa_config_add_network(wpa_s->conf);
|
||||
if (ssid == NULL) {
|
||||
@@ -2159,6 +2218,10 @@ DBusMessage * wpas_dbus_handler_remove_persistent_group(
|
||||
DBUS_TYPE_INVALID);
|
||||
|
||||
wpa_s = wpa_s->global->p2p_init_wpa_s;
|
||||
+ if (!wpa_s) {
|
||||
+ reply = wpas_dbus_error_no_p2p_mgmt_iface(message);
|
||||
+ goto out;
|
||||
+ }
|
||||
|
||||
/*
|
||||
* Extract the network ID and ensure the network is actually a child of
|
||||
@@ -2235,6 +2298,8 @@ DBusMessage * wpas_dbus_handler_remove_all_persistent_groups(
|
||||
struct wpa_config *config;
|
||||
|
||||
wpa_s = wpa_s->global->p2p_init_wpa_s;
|
||||
+ if (!wpa_s)
|
||||
+ return wpas_dbus_error_no_p2p_mgmt_iface(message);
|
||||
|
||||
config = wpa_s->conf;
|
||||
ssid = config->ssid;
|
||||
--
|
||||
2.26.2
|
||||
|
111
0001-P2P-Always-use-global-p2p_long_listen.patch
Normal file
111
0001-P2P-Always-use-global-p2p_long_listen.patch
Normal file
@ -0,0 +1,111 @@
|
||||
From 9ad3c12dd1bf56824ef8b3425e057e8d1e84e69d Mon Sep 17 00:00:00 2001
|
||||
From: Benjamin Berg <bberg@redhat.com>
|
||||
Date: Fri, 3 Jan 2020 22:18:51 +0100
|
||||
Subject: [PATCH] P2P: Always use global p2p_long_listen
|
||||
|
||||
The p2p_long_listen value was set on the control wpa_s struct while in a
|
||||
lot of cases it operated on the p2p struct. Explicitly use the global
|
||||
p2p_init_wpa_s struct in cases where we might not be operating on it
|
||||
already.
|
||||
|
||||
Without this, simply starting a p2p_listen operation (e.g., using
|
||||
wpa_cli) will not work properly. As the p2p_long_listen is set on the
|
||||
controlling interface and wpas_p2p_cancel_remain_on_channel_cb() uses
|
||||
p2p_init_wpa_s, it would not actually work. This results in
|
||||
wpa_supplicant stopping listening after the maximum remain-on-channel
|
||||
time passes when using a separate P2P Device interface.
|
||||
|
||||
Signed-off-by: Benjamin Berg <bberg@redhat.com>
|
||||
---
|
||||
wpa_supplicant/p2p_supplicant.c | 19 ++++++++++---------
|
||||
1 file changed, 10 insertions(+), 9 deletions(-)
|
||||
|
||||
diff --git a/wpa_supplicant/p2p_supplicant.c b/wpa_supplicant/p2p_supplicant.c
|
||||
index 95bacec19..a7d3b7f1d 100644
|
||||
--- a/wpa_supplicant/p2p_supplicant.c
|
||||
+++ b/wpa_supplicant/p2p_supplicant.c
|
||||
@@ -2422,7 +2422,7 @@ static void wpas_go_neg_completed(void *ctx, struct p2p_go_neg_results *res)
|
||||
wpas_start_wps_enrollee(group_wpa_s, res);
|
||||
}
|
||||
|
||||
- wpa_s->p2p_long_listen = 0;
|
||||
+ wpa_s->global->p2p_init_wpa_s->p2p_long_listen = 0;
|
||||
eloop_cancel_timeout(wpas_p2p_long_listen_timeout, wpa_s, NULL);
|
||||
|
||||
eloop_cancel_timeout(wpas_p2p_group_formation_timeout, wpa_s, NULL);
|
||||
@@ -4750,7 +4750,8 @@ void wpas_p2p_deinit(struct wpa_supplicant *wpa_s)
|
||||
eloop_cancel_timeout(wpas_p2p_psk_failure_removal, wpa_s, NULL);
|
||||
eloop_cancel_timeout(wpas_p2p_group_formation_timeout, wpa_s, NULL);
|
||||
eloop_cancel_timeout(wpas_p2p_join_scan, wpa_s, NULL);
|
||||
- wpa_s->p2p_long_listen = 0;
|
||||
+ if (wpa_s->global->p2p_init_wpa_s)
|
||||
+ wpa_s->global->p2p_init_wpa_s->p2p_long_listen = 0;
|
||||
eloop_cancel_timeout(wpas_p2p_long_listen_timeout, wpa_s, NULL);
|
||||
eloop_cancel_timeout(wpas_p2p_group_idle_timeout, wpa_s, NULL);
|
||||
wpas_p2p_remove_pending_group_interface(wpa_s);
|
||||
@@ -5635,7 +5636,7 @@ int wpas_p2p_connect(struct wpa_supplicant *wpa_s, const u8 *peer_addr,
|
||||
go_intent = wpa_s->conf->p2p_go_intent;
|
||||
|
||||
if (!auth)
|
||||
- wpa_s->p2p_long_listen = 0;
|
||||
+ wpa_s->global->p2p_init_wpa_s->p2p_long_listen = 0;
|
||||
|
||||
wpa_s->p2p_wps_method = wps_method;
|
||||
wpa_s->p2p_persistent_group = !!persistent_group;
|
||||
@@ -6952,7 +6953,7 @@ int wpas_p2p_find(struct wpa_supplicant *wpa_s, unsigned int timeout,
|
||||
u8 seek_cnt, const char **seek_string, int freq)
|
||||
{
|
||||
wpas_p2p_clear_pending_action_tx(wpa_s);
|
||||
- wpa_s->p2p_long_listen = 0;
|
||||
+ wpa_s->global->p2p_init_wpa_s->p2p_long_listen = 0;
|
||||
|
||||
if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL ||
|
||||
wpa_s->p2p_in_provisioning) {
|
||||
@@ -6997,7 +6998,7 @@ static void wpas_p2p_scan_res_ignore_search(struct wpa_supplicant *wpa_s,
|
||||
static void wpas_p2p_stop_find_oper(struct wpa_supplicant *wpa_s)
|
||||
{
|
||||
wpas_p2p_clear_pending_action_tx(wpa_s);
|
||||
- wpa_s->p2p_long_listen = 0;
|
||||
+ wpa_s->global->p2p_init_wpa_s->p2p_long_listen = 0;
|
||||
eloop_cancel_timeout(wpas_p2p_long_listen_timeout, wpa_s, NULL);
|
||||
eloop_cancel_timeout(wpas_p2p_join_scan, wpa_s, NULL);
|
||||
|
||||
@@ -7023,7 +7024,7 @@ void wpas_p2p_stop_find(struct wpa_supplicant *wpa_s)
|
||||
static void wpas_p2p_long_listen_timeout(void *eloop_ctx, void *timeout_ctx)
|
||||
{
|
||||
struct wpa_supplicant *wpa_s = eloop_ctx;
|
||||
- wpa_s->p2p_long_listen = 0;
|
||||
+ wpa_s->global->p2p_init_wpa_s->p2p_long_listen = 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -7052,7 +7053,7 @@ int wpas_p2p_listen(struct wpa_supplicant *wpa_s, unsigned int timeout)
|
||||
timeout = 3600;
|
||||
}
|
||||
eloop_cancel_timeout(wpas_p2p_long_listen_timeout, wpa_s, NULL);
|
||||
- wpa_s->p2p_long_listen = 0;
|
||||
+ wpa_s->global->p2p_init_wpa_s->p2p_long_listen = 0;
|
||||
|
||||
/*
|
||||
* Stop previous find/listen operation to avoid trying to request a new
|
||||
@@ -7064,7 +7065,7 @@ int wpas_p2p_listen(struct wpa_supplicant *wpa_s, unsigned int timeout)
|
||||
|
||||
res = wpas_p2p_listen_start(wpa_s, timeout * 1000);
|
||||
if (res == 0 && timeout * 1000 > wpa_s->max_remain_on_chan) {
|
||||
- wpa_s->p2p_long_listen = timeout * 1000;
|
||||
+ wpa_s->global->p2p_init_wpa_s->p2p_long_listen = timeout * 1000;
|
||||
eloop_register_timeout(timeout, 0,
|
||||
wpas_p2p_long_listen_timeout,
|
||||
wpa_s, NULL);
|
||||
@@ -7171,7 +7172,7 @@ static void wpas_p2p_group_deinit(struct wpa_supplicant *wpa_s)
|
||||
|
||||
int wpas_p2p_reject(struct wpa_supplicant *wpa_s, const u8 *addr)
|
||||
{
|
||||
- wpa_s->p2p_long_listen = 0;
|
||||
+ wpa_s->global->p2p_init_wpa_s->p2p_long_listen = 0;
|
||||
|
||||
if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL)
|
||||
return -1;
|
||||
--
|
||||
2.26.2
|
||||
|
@ -0,0 +1,30 @@
|
||||
From d4348cbbdbdba5d045b5b389ba6ce97b74936f30 Mon Sep 17 00:00:00 2001
|
||||
From: Benjamin Berg <bberg@redhat.com>
|
||||
Date: Mon, 15 Jun 2020 16:17:43 +0200
|
||||
Subject: [PATCH] p2p: Limit P2P_DEVICE name to appropriate ifname size
|
||||
|
||||
Otherwise the WPA_IF_P2P_DEVICE cannot be created. As this is not a
|
||||
netdev device, it is acceptable if the name is not completely unique. As
|
||||
such, simply insert a NUL byte at the appropriate place.
|
||||
---
|
||||
wpa_supplicant/p2p_supplicant.c | 4 ++++
|
||||
1 file changed, 4 insertions(+)
|
||||
|
||||
diff --git a/wpa_supplicant/p2p_supplicant.c b/wpa_supplicant/p2p_supplicant.c
|
||||
index e94bffe52..17c25889c 100644
|
||||
--- a/wpa_supplicant/p2p_supplicant.c
|
||||
+++ b/wpa_supplicant/p2p_supplicant.c
|
||||
@@ -3929,6 +3929,10 @@ int wpas_p2p_add_p2pdev_interface(struct wpa_supplicant *wpa_s,
|
||||
wpa_s->ifname);
|
||||
if (os_snprintf_error(sizeof(ifname), ret))
|
||||
return -1;
|
||||
+ /* Cut length at the maximum size. Note that we don't need to ensure
|
||||
+ * collision free names here as the created interface is not a netdev.
|
||||
+ */
|
||||
+ ifname[IFNAMSIZ-1] = '\0';
|
||||
force_name[0] = '\0';
|
||||
wpa_s->pending_interface_type = WPA_IF_P2P_DEVICE;
|
||||
ret = wpa_drv_if_add(wpa_s, WPA_IF_P2P_DEVICE, ifname, NULL, NULL,
|
||||
--
|
||||
2.26.2
|
||||
|
@ -5,7 +5,7 @@ Summary: WPA/WPA2/IEEE 802.1X Supplicant
|
||||
Name: wpa_supplicant
|
||||
Epoch: 1
|
||||
Version: 2.9
|
||||
Release: 4%{?dist}
|
||||
Release: 5%{?dist}
|
||||
License: BSD
|
||||
Source0: http://w1.fi/releases/%{name}-%{version}.tar.gz
|
||||
Source1: wpa_supplicant.conf
|
||||
@ -28,6 +28,11 @@ Patch4: wpa_supplicant-gui-qt4.patch
|
||||
# fix AP mode PMF disconnection protection bypass
|
||||
Patch5: 0001-AP-Silently-ignore-management-frame-from-unexpected-.patch
|
||||
|
||||
# fix some issues with P2P operation
|
||||
Patch6: 0001-P2P-Always-use-global-p2p_long_listen.patch
|
||||
Patch7: 0001-D-Bus-Fix-P2P-NULL-dereference-after-interface-remov.patch
|
||||
Patch8: 0001-p2p-Limit-P2P_DEVICE-name-to-appropriate-ifname-size.patch
|
||||
|
||||
URL: http://w1.fi/wpa_supplicant/
|
||||
|
||||
%if %with gui
|
||||
@ -183,6 +188,9 @@ chmod -R 0644 wpa_supplicant/examples/*.py
|
||||
|
||||
|
||||
%changelog
|
||||
* Mon Jun 15 2020 Benjamin Berg <bberg@redhat.com> - 1:2.9-5
|
||||
- fix some issues with P2P operation
|
||||
|
||||
* Thu Apr 23 2020 Davide Caratti <dcaratti@redhat.com> - 1:2.9-4
|
||||
- Enable Tunneled Direct Link Setup (TDLS)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user