From aa89df56996c0da499f1cdb132893c1863b6b2fb Mon Sep 17 00:00:00 2001 From: Todd Previte Date: Sat, 4 Feb 2012 13:08:12 +0200 Subject: [PATCH] P2P: Fix DBus crash and return additional P2P group properties When using DBus to get group properties, a segmentation fault is generated on P2P clients due to a NULL pointer for the ap_iface struct. The current implementation only returns vendor extensions when called on a P2P group owner. The code now checks the P2P role which allows for role-specific information to be provided. This also fixes the crash issue by only looking for the correct structures based on the current P2P role. Signed-hostap: Todd Previte Signed-hostap: Angie Chinchilla intended-for: hostap-1 --- wpa_supplicant/dbus/dbus_new_handlers_p2p.c | 88 +++++++++++++++++---- 1 file changed, 73 insertions(+), 15 deletions(-) diff --git a/wpa_supplicant/dbus/dbus_new_handlers_p2p.c b/wpa_supplicant/dbus/dbus_new_handlers_p2p.c index 0f6914c83..2476e6216 100644 --- a/wpa_supplicant/dbus/dbus_new_handlers_p2p.c +++ b/wpa_supplicant/dbus/dbus_new_handlers_p2p.c @@ -1664,14 +1664,41 @@ dbus_bool_t wpas_dbus_getter_p2p_group_properties(DBusMessageIter *iter, { struct wpa_supplicant *wpa_s = user_data; DBusMessageIter variant_iter, dict_iter; - struct hostapd_data *hapd = wpa_s->ap_iface->bss[0]; + struct hostapd_data *hapd = NULL; const struct wpabuf *vendor_ext[MAX_WPS_VENDOR_EXTENSIONS]; int num_vendor_ext = 0; int i; + u8 role = wpas_get_p2p_role(wpa_s); + u16 op_freq = 0; + u8 *p_bssid = NULL; + char *role_name = NULL; - if (!hapd) { - dbus_set_error_const(error, DBUS_ERROR_FAILED, - "internal error"); + if (!wpa_s->current_ssid) + return FALSE; + + /* Check current role and adjust information accordingly */ + switch (role) { + case WPAS_P2P_ROLE_CLIENT: + /* go_params is only valid for a client */ + if (wpa_s->go_params) { + op_freq = wpa_s->go_params->freq; + p_bssid = wpa_s->current_ssid->bssid; + role_name = "client"; + } else + return FALSE; + break; + case WPAS_P2P_ROLE_GO: + /* ap_iface is only valid for a GO */ + if (wpa_s->ap_iface) { + hapd = wpa_s->ap_iface->bss[0]; + p_bssid = hapd->own_addr; + op_freq = wpa_s->ap_iface->freq; + role_name = "GO"; + } else + return FALSE; + break; + default: + /* Error condition; this should NEVER occur */ return FALSE; } @@ -1679,18 +1706,49 @@ dbus_bool_t wpas_dbus_getter_p2p_group_properties(DBusMessageIter *iter, "a{sv}", &variant_iter) || !wpa_dbus_dict_open_write(&variant_iter, &dict_iter)) goto err_no_mem; - - /* Parse WPS Vendor Extensions sent in Beacon/Probe Response */ - for (i = 0; i < MAX_WPS_VENDOR_EXTENSIONS; i++) { - if (hapd->conf->wps_vendor_ext[i] == NULL) - continue; - vendor_ext[num_vendor_ext++] = hapd->conf->wps_vendor_ext[i]; - } - - if (!wpa_dbus_dict_append_wpabuf_array(&dict_iter, - "WPSVendorExtensions", - vendor_ext, num_vendor_ext)) + /* Provide the SSID */ + if (!wpa_dbus_dict_append_byte_array( + &dict_iter, "SSID", + (const char *) wpa_s->current_ssid->ssid, + wpa_s->current_ssid->ssid_len)) goto err_no_mem; + /* Provide the BSSID */ + if (p_bssid && + !wpa_dbus_dict_append_byte_array(&dict_iter, "BSSID", + (const char *) p_bssid, ETH_ALEN)) + goto err_no_mem; + /* Provide the role within the group */ + if (role_name && + !wpa_dbus_dict_append_string(&dict_iter, "Role", role_name)) + goto err_no_mem; + /* Provide the operational frequency */ + if (!wpa_dbus_dict_append_uint16(&dict_iter, "Frequency", op_freq)) + goto err_no_mem; + + /* Additional information for group owners */ + if (role == WPAS_P2P_ROLE_GO) { + /* Provide the passphrase */ + if (!wpa_dbus_dict_append_string(&dict_iter, "Passphrase", + wpa_s->current_ssid->passphrase)) + goto err_no_mem; + /* Parse WPS Vendor Extensions sent in Beacon/Probe Response */ + for (i = 0; hapd && i < MAX_WPS_VENDOR_EXTENSIONS; i++) { + if (hapd->conf->wps_vendor_ext[i] == NULL) + continue; + vendor_ext[num_vendor_ext++] = + hapd->conf->wps_vendor_ext[i]; + } + if (!wpa_dbus_dict_append_wpabuf_array(&dict_iter, + "WPSVendorExtensions", + vendor_ext, num_vendor_ext)) + goto err_no_mem; + } else { + /* If not a GO, provide the PSK */ + if (!wpa_dbus_dict_append_byte_array( + &dict_iter, "PSK", + (const char *) wpa_s->current_ssid->psk, 32)) + goto err_no_mem; + } if (!wpa_dbus_dict_close_write(&variant_iter, &dict_iter) || !dbus_message_iter_close_container(iter, &variant_iter))