|
@@ -327,13 +327,15 @@ void p2p_buf_add_p2p_interface(struct wpabuf *buf, struct p2p_data *p2p)
|
|
|
}
|
|
|
|
|
|
|
|
|
-static void p2p_add_wps_string(struct wpabuf *buf, enum wps_attribute attr,
|
|
|
- const char *val)
|
|
|
+static int p2p_add_wps_string(struct wpabuf *buf, enum wps_attribute attr,
|
|
|
+ const char *val)
|
|
|
{
|
|
|
size_t len;
|
|
|
|
|
|
- wpabuf_put_be16(buf, attr);
|
|
|
len = val ? os_strlen(val) : 0;
|
|
|
+ if (wpabuf_tailroom(buf) < 4 + len)
|
|
|
+ return -1;
|
|
|
+ wpabuf_put_be16(buf, attr);
|
|
|
#ifndef CONFIG_WPS_STRICT
|
|
|
if (len == 0) {
|
|
|
/*
|
|
@@ -341,36 +343,46 @@ static void p2p_add_wps_string(struct wpabuf *buf, enum wps_attribute attr,
|
|
|
* attributes. As a workaround, send a space character if the
|
|
|
* device attribute string is empty.
|
|
|
*/
|
|
|
+ if (wpabuf_tailroom(buf) < 3)
|
|
|
+ return -1;
|
|
|
wpabuf_put_be16(buf, 1);
|
|
|
wpabuf_put_u8(buf, ' ');
|
|
|
- return;
|
|
|
+ return 0;
|
|
|
}
|
|
|
#endif /* CONFIG_WPS_STRICT */
|
|
|
wpabuf_put_be16(buf, len);
|
|
|
if (val)
|
|
|
wpabuf_put_data(buf, val, len);
|
|
|
+ return 0;
|
|
|
}
|
|
|
|
|
|
|
|
|
-void p2p_build_wps_ie(struct p2p_data *p2p, struct wpabuf *buf, int pw_id,
|
|
|
- int all_attr)
|
|
|
+int p2p_build_wps_ie(struct p2p_data *p2p, struct wpabuf *buf, int pw_id,
|
|
|
+ int all_attr)
|
|
|
{
|
|
|
u8 *len;
|
|
|
int i;
|
|
|
|
|
|
+ if (wpabuf_tailroom(buf) < 6)
|
|
|
+ return -1;
|
|
|
wpabuf_put_u8(buf, WLAN_EID_VENDOR_SPECIFIC);
|
|
|
len = wpabuf_put(buf, 1);
|
|
|
wpabuf_put_be32(buf, WPS_DEV_OUI_WFA);
|
|
|
|
|
|
- wps_build_version(buf);
|
|
|
+ if (wps_build_version(buf) < 0)
|
|
|
+ return -1;
|
|
|
|
|
|
if (all_attr) {
|
|
|
+ if (wpabuf_tailroom(buf) < 5)
|
|
|
+ return -1;
|
|
|
wpabuf_put_be16(buf, ATTR_WPS_STATE);
|
|
|
wpabuf_put_be16(buf, 1);
|
|
|
wpabuf_put_u8(buf, WPS_STATE_NOT_CONFIGURED);
|
|
|
}
|
|
|
|
|
|
if (pw_id >= 0) {
|
|
|
+ if (wpabuf_tailroom(buf) < 6)
|
|
|
+ return -1;
|
|
|
/* Device Password ID */
|
|
|
wpabuf_put_be16(buf, ATTR_DEV_PASSWORD_ID);
|
|
|
wpabuf_put_be16(buf, 2);
|
|
@@ -380,33 +392,47 @@ void p2p_build_wps_ie(struct p2p_data *p2p, struct wpabuf *buf, int pw_id,
|
|
|
}
|
|
|
|
|
|
if (all_attr) {
|
|
|
+ if (wpabuf_tailroom(buf) < 5)
|
|
|
+ return -1;
|
|
|
wpabuf_put_be16(buf, ATTR_RESPONSE_TYPE);
|
|
|
wpabuf_put_be16(buf, 1);
|
|
|
wpabuf_put_u8(buf, WPS_RESP_ENROLLEE_INFO);
|
|
|
|
|
|
- wps_build_uuid_e(buf, p2p->cfg->uuid);
|
|
|
- p2p_add_wps_string(buf, ATTR_MANUFACTURER,
|
|
|
- p2p->cfg->manufacturer);
|
|
|
- p2p_add_wps_string(buf, ATTR_MODEL_NAME, p2p->cfg->model_name);
|
|
|
- p2p_add_wps_string(buf, ATTR_MODEL_NUMBER,
|
|
|
- p2p->cfg->model_number);
|
|
|
- p2p_add_wps_string(buf, ATTR_SERIAL_NUMBER,
|
|
|
- p2p->cfg->serial_number);
|
|
|
-
|
|
|
+ if (wps_build_uuid_e(buf, p2p->cfg->uuid) < 0 ||
|
|
|
+ p2p_add_wps_string(buf, ATTR_MANUFACTURER,
|
|
|
+ p2p->cfg->manufacturer) < 0 ||
|
|
|
+ p2p_add_wps_string(buf, ATTR_MODEL_NAME,
|
|
|
+ p2p->cfg->model_name) < 0 ||
|
|
|
+ p2p_add_wps_string(buf, ATTR_MODEL_NUMBER,
|
|
|
+ p2p->cfg->model_number) < 0 ||
|
|
|
+ p2p_add_wps_string(buf, ATTR_SERIAL_NUMBER,
|
|
|
+ p2p->cfg->serial_number) < 0)
|
|
|
+ return -1;
|
|
|
+
|
|
|
+ if (wpabuf_tailroom(buf) < 4 + WPS_DEV_TYPE_LEN)
|
|
|
+ return -1;
|
|
|
wpabuf_put_be16(buf, ATTR_PRIMARY_DEV_TYPE);
|
|
|
wpabuf_put_be16(buf, WPS_DEV_TYPE_LEN);
|
|
|
wpabuf_put_data(buf, p2p->cfg->pri_dev_type, WPS_DEV_TYPE_LEN);
|
|
|
|
|
|
- p2p_add_wps_string(buf, ATTR_DEV_NAME, p2p->cfg->dev_name);
|
|
|
+ if (p2p_add_wps_string(buf, ATTR_DEV_NAME, p2p->cfg->dev_name)
|
|
|
+ < 0)
|
|
|
+ return -1;
|
|
|
|
|
|
+ if (wpabuf_tailroom(buf) < 6)
|
|
|
+ return -1;
|
|
|
wpabuf_put_be16(buf, ATTR_CONFIG_METHODS);
|
|
|
wpabuf_put_be16(buf, 2);
|
|
|
wpabuf_put_be16(buf, p2p->cfg->config_methods);
|
|
|
}
|
|
|
|
|
|
- wps_build_wfa_ext(buf, 0, NULL, 0);
|
|
|
+ if (wps_build_wfa_ext(buf, 0, NULL, 0) < 0)
|
|
|
+ return -1;
|
|
|
|
|
|
if (all_attr && p2p->cfg->num_sec_dev_types) {
|
|
|
+ if (wpabuf_tailroom(buf) <
|
|
|
+ 4 + WPS_DEV_TYPE_LEN * p2p->cfg->num_sec_dev_types)
|
|
|
+ return -1;
|
|
|
wpabuf_put_be16(buf, ATTR_SECONDARY_DEV_TYPE_LIST);
|
|
|
wpabuf_put_be16(buf, WPS_DEV_TYPE_LEN *
|
|
|
p2p->cfg->num_sec_dev_types);
|
|
@@ -428,4 +454,6 @@ void p2p_build_wps_ie(struct p2p_data *p2p, struct wpabuf *buf, int pw_id,
|
|
|
}
|
|
|
|
|
|
p2p_buf_update_ie_hdr(buf, len);
|
|
|
+
|
|
|
+ return 0;
|
|
|
}
|