end = ies + ies_len;
- for (pos = ies; pos + 1 < end; pos += len) {
+ for (pos = ies; end - pos > 1; pos += len) {
id = *pos++;
len = *pos++;
- if (pos + len > end)
+ if (len > end - pos)
break;
if (id != WLAN_EID_VENDOR_SPECIFIC || len < 3)
{
const u8 *pos, *end;
struct p2p_channels *ch;
- size_t channels;
+ u8 channels;
struct p2p_channels intersection;
ch = &dev->channels;
}
pos += 3;
- while (pos + 2 < end) {
+ while (end - pos > 2) {
struct p2p_reg_class *cl = &ch->reg_class[ch->reg_classes];
cl->reg_class = *pos++;
- if (pos + 1 + pos[0] > end) {
+ channels = *pos++;
+ if (channels > end - pos) {
p2p_info(p2p, "Invalid peer Channel List");
return -1;
}
- channels = *pos++;
cl->channels = channels > P2P_MAX_REG_CLASS_CHANNELS ?
P2P_MAX_REG_CLASS_CHANNELS : channels;
os_memcpy(cl->channel, pos, cl->channels);
os_memset(zero_addr, 0, ETH_ALEN);
pos = wpabuf_head_u8(m->wfd_ie);
end = pos + wpabuf_len(m->wfd_ie);
- while (pos + 1 < end) {
+ while (end - pos >= 3) {
u8 id;
u16 len;
id = *pos++;
len = WPA_GET_BE16(pos);
pos += 2;
- if (pos + len > end)
+ if (len > end - pos)
break;
switch (id) {
struct p2p_message *msg)
{
const u8 *pos;
- size_t i, nlen;
+ size_t i;
+ u16 nlen;
char devtype[WPS_DEV_TYPE_BUFSIZE];
switch (id) {
pos += 2;
nlen = WPA_GET_BE16(pos);
pos += 2;
- if (data + len - pos < (int) nlen ||
- nlen > WPS_DEV_NAME_MAX_LEN) {
+ if (nlen > data + len - pos || nlen > WPS_DEV_NAME_MAX_LEN) {
wpa_printf(MSG_DEBUG, "P2P: Invalid Device Name "
- "length %d (buf len %d)", (int) nlen,
+ "length %u (buf len %d)", nlen,
(int) (data + len - pos));
return -1;
}
gend = gi + gi_len;
while (g < gend) {
struct p2p_client_info *cli;
- const u8 *t, *cend;
- int count;
+ const u8 *cend;
+ u16 count;
+ u8 len;
cli = &info->client[info->num_clients];
- cend = g + 1 + g[0];
- if (cend > gend)
+ len = *g++;
+ if (len > gend - g || len < 2 * ETH_ALEN + 1 + 2 + 8 + 1)
return -1; /* invalid data */
+ cend = g + len;
/* g at start of P2P Client Info Descriptor */
- /* t at Device Capability Bitmap */
- t = g + 1 + 2 * ETH_ALEN;
- if (t > cend)
- return -1; /* invalid data */
- cli->p2p_device_addr = g + 1;
- cli->p2p_interface_addr = g + 1 + ETH_ALEN;
- cli->dev_capab = t[0];
-
- if (t + 1 + 2 + 8 + 1 > cend)
- return -1; /* invalid data */
-
- cli->config_methods = WPA_GET_BE16(&t[1]);
- cli->pri_dev_type = &t[3];
-
- t += 1 + 2 + 8;
- /* t at Number of Secondary Device Types */
- cli->num_sec_dev_types = *t++;
- if (t + 8 * cli->num_sec_dev_types > cend)
+ cli->p2p_device_addr = g;
+ g += ETH_ALEN;
+ cli->p2p_interface_addr = g;
+ g += ETH_ALEN;
+ cli->dev_capab = *g++;
+
+ cli->config_methods = WPA_GET_BE16(g);
+ g += 2;
+ cli->pri_dev_type = g;
+ g += 8;
+
+ /* g at Number of Secondary Device Types */
+ len = *g++;
+ if (8 * len > cend - g)
return -1; /* invalid data */
- cli->sec_dev_types = t;
- t += 8 * cli->num_sec_dev_types;
+ cli->num_sec_dev_types = len;
+ cli->sec_dev_types = g;
+ g += 8 * len;
- /* t at Device Name in WPS TLV format */
- if (t + 2 + 2 > cend)
+ /* g at Device Name in WPS TLV format */
+ if (cend - g < 2 + 2)
return -1; /* invalid data */
- if (WPA_GET_BE16(t) != ATTR_DEV_NAME)
+ if (WPA_GET_BE16(g) != ATTR_DEV_NAME)
return -1; /* invalid Device Name TLV */
- t += 2;
- count = WPA_GET_BE16(t);
- t += 2;
- if (count > cend - t)
+ g += 2;
+ count = WPA_GET_BE16(g);
+ g += 2;
+ if (count > cend - g)
return -1; /* invalid Device Name TLV */
if (count >= WPS_DEV_NAME_MAX_LEN)
count = WPS_DEV_NAME_MAX_LEN;
- cli->dev_name = (const char *) t;
+ cli->dev_name = (const char *) g;
cli->dev_name_len = count;
g = cend;
pos = wpabuf_head(wfd);
end = pos + wpabuf_len(wfd);
- while (pos + 3 <= end) {
+ while (end - pos >= 3) {
subelem = *pos++;
len = WPA_GET_BE16(pos);
pos += 2;
- if (pos + len > end)
+ if (len > end - pos)
break;
if (subelem == WFD_SUBELEM_DEVICE_INFO && len >= 6) {
pos++;
slen = *pos++;
- next = pos + slen;
- if (next > end || slen < 2) {
+ if (slen > end - pos || slen < 2) {
p2p_dbg(p2p, "Invalid IE in GAS Initial Request");
return;
}
+ next = pos + slen;
pos++; /* skip QueryRespLenLimit and PAME-BI */
if (*pos != ACCESS_NETWORK_QUERY_PROTOCOL) {
pos = next;
/* Query Request */
- if (pos + 2 > end)
+ if (end - pos < 2)
return;
slen = WPA_GET_LE16(pos);
pos += 2;
- if (pos + slen > end)
+ if (slen > end - pos)
return;
end = pos + slen;
/* ANQP Query Request */
- if (pos + 4 > end)
+ if (end - pos < 4)
return;
if (WPA_GET_LE16(pos) != ANQP_VENDOR_SPECIFIC) {
p2p_dbg(p2p, "Unsupported ANQP Info ID %u", WPA_GET_LE16(pos));
slen = WPA_GET_LE16(pos);
pos += 2;
- if (pos + slen > end || slen < 3 + 1) {
+ if (slen > end - pos || slen < 3 + 1) {
p2p_dbg(p2p, "Invalid ANQP Query Request length");
return;
}
}
pos += 4;
- if (pos + 2 > end)
+ if (end - pos < 2)
return;
update_indic = WPA_GET_LE16(pos);
p2p_dbg(p2p, "Service Update Indicator: %u", update_indic);
pos++;
slen = *pos++;
- next = pos + slen;
- if (next > end || slen < 2) {
+ if (slen > end - pos || slen < 2) {
p2p_dbg(p2p, "Invalid IE in GAS Initial Response");
return;
}
+ next = pos + slen;
pos++; /* skip QueryRespLenLimit and PAME-BI */
if (*pos != ACCESS_NETWORK_QUERY_PROTOCOL) {
pos = next;
/* Query Response */
- if (pos + 2 > end) {
+ if (end - pos < 2) {
p2p_dbg(p2p, "Too short Query Response");
return;
}
slen = WPA_GET_LE16(pos);
pos += 2;
p2p_dbg(p2p, "Query Response Length: %d", slen);
- if (pos + slen > end) {
+ if (slen > end - pos) {
p2p_dbg(p2p, "Not enough Query Response data");
return;
}
}
/* ANQP Query Response */
- if (pos + 4 > end)
+ if (end - pos < 4)
return;
if (WPA_GET_LE16(pos) != ANQP_VENDOR_SPECIFIC) {
p2p_dbg(p2p, "Unsupported ANQP Info ID %u", WPA_GET_LE16(pos));
slen = WPA_GET_LE16(pos);
pos += 2;
- if (pos + slen > end || slen < 3 + 1) {
+ if (slen > end - pos || slen < 3 + 1) {
p2p_dbg(p2p, "Invalid ANQP Query Response length");
return;
}
}
pos += 4;
- if (pos + 2 > end)
+ if (end - pos < 2)
return;
update_indic = WPA_GET_LE16(pos);
p2p_dbg(p2p, "Service Update Indicator: %u", update_indic);
pos++;
slen = *pos++;
- next = pos + slen;
- if (next > end || slen < 2) {
+ if (slen > end - pos || slen < 2) {
p2p_dbg(p2p, "Invalid IE in GAS Comeback Response");
return;
}
+ next = pos + slen;
pos++; /* skip QueryRespLenLimit and PAME-BI */
if (*pos != ACCESS_NETWORK_QUERY_PROTOCOL) {
pos = next;
/* Query Response */
- if (pos + 2 > end) {
+ if (end - pos < 2) {
p2p_dbg(p2p, "Too short Query Response");
return;
}
slen = WPA_GET_LE16(pos);
pos += 2;
p2p_dbg(p2p, "Query Response Length: %d", slen);
- if (pos + slen > end) {
+ if (slen > end - pos) {
p2p_dbg(p2p, "Not enough Query Response data");
return;
}
}
/* ANQP Query Response */
- if (pos + 4 > end)
+ if (end - pos < 4)
return;
if (WPA_GET_LE16(pos) != ANQP_VENDOR_SPECIFIC) {
p2p_dbg(p2p, "Unsupported ANQP Info ID %u", WPA_GET_LE16(pos));
p2p_dbg(p2p, "Invalid ANQP Query Response length");
return;
}
- if (pos + 4 > end)
+ if (end - pos < 4)
return;
if (WPA_GET_BE32(pos) != P2P_IE_VENDOR_TYPE) {
}
pos += 4;
- if (pos + 2 > end)
+ if (end - pos < 2)
return;
p2p->sd_rx_update_indic = WPA_GET_LE16(pos);
p2p_dbg(p2p, "Service Update Indicator: %u", p2p->sd_rx_update_indic);