P2P: Override P2P_PEER group_capab with 0 if no matching BSS entry found

Relying on the group_capab from the P2P peer information can result in
improper information on whether the peer is currently operating as a GO.
However, there is a known implementation in Android that does this.

To reduce issues from this misuse in upper layer to try to determine
whether a specific peer is operationg a group, override the group_capab
value in P2P_PEER output with 0 if there are no BSS entries with the
peer P2P Device as a GO. This is not a perfect information since there
may not have been a recent scan on all channels, but this results in
less issues than trying to decide between new group formation and
joining an existing group based on stale or incorrect information.

Since no upper layer application is really supposed to use the
group_capab field value in P2P_PEER command, this change should not
cause any impact for properly design components and the possibility of
regressions is limited to cases that are already known to work
incorrectly in number of identifiable cases.

Signed-off-by: Jouni Malinen <jouni@qca.qualcomm.com>
This commit is contained in:
Sunil Dutt 2017-02-01 00:27:06 +05:30 committed by Jouni Malinen
parent bcf66493cf
commit f47f936170

View file

@ -6038,10 +6038,24 @@ static int p2p_ctrl_group_member(struct wpa_supplicant *wpa_s, const char *cmd,
} }
static int wpas_find_p2p_dev_addr_bss(struct wpa_global *global,
const u8 *p2p_dev_addr)
{
struct wpa_supplicant *wpa_s;
for (wpa_s = global->ifaces; wpa_s; wpa_s = wpa_s->next) {
if (wpa_bss_get_p2p_dev_addr(wpa_s, p2p_dev_addr))
return 1;
}
return 0;
}
static int p2p_ctrl_peer(struct wpa_supplicant *wpa_s, char *cmd, static int p2p_ctrl_peer(struct wpa_supplicant *wpa_s, char *cmd,
char *buf, size_t buflen) char *buf, size_t buflen)
{ {
u8 addr[ETH_ALEN], *addr_ptr; u8 addr[ETH_ALEN], *addr_ptr, group_capab;
int next, res; int next, res;
const struct p2p_peer_info *info; const struct p2p_peer_info *info;
char *pos, *end; char *pos, *end;
@ -6070,6 +6084,16 @@ static int p2p_ctrl_peer(struct wpa_supplicant *wpa_s, char *cmd,
info = p2p_get_peer_info(wpa_s->global->p2p, addr_ptr, next); info = p2p_get_peer_info(wpa_s->global->p2p, addr_ptr, next);
if (info == NULL) if (info == NULL)
return -1; return -1;
group_capab = info->group_capab;
if (group_capab &&
!wpas_find_p2p_dev_addr_bss(wpa_s->global, info->p2p_device_addr)) {
wpa_printf(MSG_DEBUG,
"P2P: Could not find any BSS with p2p_dev_addr "
MACSTR ", hence override group_capab from 0x%x to 0",
MAC2STR(info->p2p_device_addr), group_capab);
group_capab = 0;
}
pos = buf; pos = buf;
end = buf + buflen; end = buf + buflen;
@ -6095,7 +6119,7 @@ static int p2p_ctrl_peer(struct wpa_supplicant *wpa_s, char *cmd,
info->serial_number, info->serial_number,
info->config_methods, info->config_methods,
info->dev_capab, info->dev_capab,
info->group_capab, group_capab,
info->level); info->level);
if (os_snprintf_error(end - pos, res)) if (os_snprintf_error(end - pos, res))
return pos - buf; return pos - buf;