Parcourir la source

Add dup_binstr() to help common binary string tasks

There are quite a few places in the current implementation where a nul
terminated string is generated from binary data. Add a helper function
to simplify the code a bit.

Signed-hostap: Jouni Malinen <j@w1.fi>
Jouni Malinen il y a 12 ans
Parent
commit
5e24dc8a4b

+ 2 - 7
src/ap/ieee802_1x.c

@@ -399,15 +399,13 @@ static void ieee802_1x_learn_identity(struct hostapd_data *hapd,
 
 	/* Save station identity for future RADIUS packets */
 	os_free(sm->identity);
-	sm->identity = os_malloc(identity_len + 1);
+	sm->identity = (u8 *) dup_binstr(identity, identity_len);
 	if (sm->identity == NULL) {
 		sm->identity_len = 0;
 		return;
 	}
 
-	os_memcpy(sm->identity, identity, identity_len);
 	sm->identity_len = identity_len;
-	sm->identity[identity_len] = '\0';
 	hostapd_logger(hapd, sm->addr, HOSTAPD_MODULE_IEEE8021X,
 		       HOSTAPD_LEVEL_DEBUG, "STA identity '%s'", sm->identity);
 	sm->dot1xAuthEapolRespIdFramesRx++;
@@ -1272,13 +1270,10 @@ static void ieee802_1x_update_sta_identity(struct hostapd_data *hapd,
 				    NULL) < 0)
 		return;
 
-	identity = os_malloc(len + 1);
+	identity = (u8 *) dup_binstr(buf, len);
 	if (identity == NULL)
 		return;
 
-	os_memcpy(identity, buf, len);
-	identity[len] = '\0';
-
 	hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE8021X,
 		       HOSTAPD_LEVEL_DEBUG, "old identity '%s' updated with "
 		       "User-Name from Access-Accept '%s'",

+ 2 - 14
src/drivers/driver_ndis.c

@@ -2110,14 +2110,8 @@ static int wpa_driver_ndis_get_names(struct wpa_driver_ndis_data *drv)
 		dlen = dpos - desc;
 	else
 		dlen = os_strlen(desc);
-	drv->adapter_desc = os_malloc(dlen + 1);
-	if (drv->adapter_desc) {
-		os_memcpy(drv->adapter_desc, desc, dlen);
-		drv->adapter_desc[dlen] = '\0';
-	}
-
+	drv->adapter_desc = dup_binstr(desc, dlen);
 	os_free(b);
-
 	if (drv->adapter_desc == NULL)
 		return -1;
 
@@ -2284,14 +2278,8 @@ static int wpa_driver_ndis_get_names(struct wpa_driver_ndis_data *drv)
 	} else {
 		dlen = os_strlen(desc[i]);
 	}
-	drv->adapter_desc = os_malloc(dlen + 1);
-	if (drv->adapter_desc) {
-		os_memcpy(drv->adapter_desc, desc[i], dlen);
-		drv->adapter_desc[dlen] = '\0';
-	}
-
+	drv->adapter_desc = dup_binstr(desc[i], dlen);
 	os_free(names);
-
 	if (drv->adapter_desc == NULL)
 		return -1;
 

+ 1 - 3
src/drivers/driver_wext.c

@@ -502,11 +502,9 @@ static void wpa_driver_wext_event_wireless(struct wpa_driver_wext_data *drv,
 					   "IWEVCUSTOM length");
 				return;
 			}
-			buf = os_malloc(iwe->u.data.length + 1);
+			buf = dup_binstr(custom, iwe->u.data.length);
 			if (buf == NULL)
 				return;
-			os_memcpy(buf, custom, iwe->u.data.length);
-			buf[iwe->u.data.length] = '\0';
 			wpa_driver_wext_event_wireless_custom(drv->ctx, buf);
 			os_free(buf);
 			break;

+ 1 - 3
src/eap_peer/eap_mschapv2.c

@@ -644,10 +644,8 @@ static struct wpabuf * eap_mschapv2_failure(struct eap_sm *sm,
 	 * must allocate a large enough temporary buffer to create that since
 	 * the received message does not include nul termination.
 	 */
-	buf = os_malloc(len + 1);
+	buf = dup_binstr(msdata, len);
 	if (buf) {
-		os_memcpy(buf, msdata, len);
-		buf[len] = '\0';
 		retry = eap_mschapv2_failure_txt(sm, data, buf);
 		os_free(buf);
 	}

+ 1 - 3
src/eap_peer/tncc.c

@@ -741,12 +741,10 @@ enum tncc_process_res tncc_process_if_tnccs(struct tncc_data *tncc,
 	enum tncc_process_res res = TNCCS_PROCESS_OK_NO_RECOMMENDATION;
 	int recommendation_msg = 0;
 
-	buf = os_malloc(len + 1);
+	buf = dup_binstr(msg, len);
 	if (buf == NULL)
 		return TNCCS_PROCESS_ERROR;
 
-	os_memcpy(buf, msg, len);
-	buf[len] = '\0';
 	start = os_strstr(buf, "<TNCCS-Batch ");
 	end = os_strstr(buf, "</TNCCS-Batch>");
 	if (start == NULL || end == NULL || start > end) {

+ 1 - 8
src/eap_server/eap_sim_db.c

@@ -1480,7 +1480,6 @@ int eap_sim_db_resynchronize(struct eap_sim_db_data *data,
  */
 char * sim_get_username(const u8 *identity, size_t identity_len)
 {
-	char *username;
 	size_t pos;
 
 	if (identity == NULL)
@@ -1491,11 +1490,5 @@ char * sim_get_username(const u8 *identity, size_t identity_len)
 			break;
 	}
 
-	username = os_malloc(pos + 1);
-	if (username == NULL)
-		return NULL;
-	os_memcpy(username, identity, pos);
-	username[pos] = '\0';
-
-	return username;
+	return dup_binstr(identity, pos);
 }

+ 1 - 3
src/eap_server/tncs.c

@@ -851,12 +851,10 @@ enum tncs_process_res tncs_process_if_tnccs(struct tncs_data *tncs,
 	unsigned char *decoded;
 	size_t decoded_len;
 
-	buf = os_malloc(len + 1);
+	buf = dup_binstr(msg, len);
 	if (buf == NULL)
 		return TNCCS_PROCESS_ERROR;
 
-	os_memcpy(buf, msg, len);
-	buf[len] = '\0';
 	start = os_strstr(buf, "<TNCCS-Batch ");
 	end = os_strstr(buf, "</TNCCS-Batch>");
 	if (start == NULL || end == NULL || start > end) {

+ 2 - 3
src/tls/x509v3.c

@@ -443,17 +443,16 @@ static int x509_parse_name(const u8 *buf, size_t len, struct x509_name *name,
 			return -1;
 		}
 
-		val = os_malloc(hdr.length + 1);
+		val = dup_binstr(hdr.payload, hdr.length);
 		if (val == NULL) {
 			x509_free_name(name);
 			return -1;
 		}
-		os_memcpy(val, hdr.payload, hdr.length);
-		val[hdr.length] = '\0';
 		if (os_strlen(val) != hdr.length) {
 			wpa_printf(MSG_INFO, "X509: Reject certificate with "
 				   "embedded NUL byte in a string (%s[NUL])",
 				   val);
+			os_free(val);
 			x509_free_name(name);
 			return -1;
 		}

+ 18 - 6
src/utils/common.c

@@ -517,11 +517,9 @@ char * wpa_config_parse_string(const char *value, size_t *len)
 		if (pos == NULL || pos[1] != '\0')
 			return NULL;
 		*len = pos - value;
-		str = os_malloc(*len + 1);
+		str = dup_binstr(value, *len);
 		if (str == NULL)
 			return NULL;
-		os_memcpy(str, value, *len);
-		str[*len] = '\0';
 		return str;
 	} else if (*value == 'P' && value[1] == '"') {
 		const char *pos;
@@ -532,11 +530,9 @@ char * wpa_config_parse_string(const char *value, size_t *len)
 		if (pos == NULL || pos[1] != '\0')
 			return NULL;
 		tlen = pos - value;
-		tstr = os_malloc(tlen + 1);
+		tstr = dup_binstr(value, tlen);
 		if (tstr == NULL)
 			return NULL;
-		os_memcpy(tstr, value, tlen);
-		tstr[tlen] = '\0';
 
 		str = os_malloc(tlen + 1);
 		if (str == NULL) {
@@ -610,3 +606,19 @@ size_t merge_byte_arrays(u8 *res, size_t res_len,
 
 	return len;
 }
+
+
+char * dup_binstr(const void *src, size_t len)
+{
+	char *res;
+
+	if (src == NULL)
+		return NULL;
+	res = os_malloc(len + 1);
+	if (res == NULL)
+		return NULL;
+	os_memcpy(res, src, len);
+	res[len] = '\0';
+
+	return res;
+}

+ 1 - 0
src/utils/common.h

@@ -487,6 +487,7 @@ int is_hex(const u8 *data, size_t len);
 size_t merge_byte_arrays(u8 *res, size_t res_len,
 			 const u8 *src1, size_t src1_len,
 			 const u8 *src2, size_t src2_len);
+char * dup_binstr(const void *src, size_t len);
 
 static inline int is_zero_ether_addr(const u8 *a)
 {

+ 5 - 15
src/wps/wps_dev_attr.c

@@ -257,11 +257,9 @@ static int wps_process_manufacturer(struct wps_device_data *dev, const u8 *str,
 	wpa_hexdump_ascii(MSG_DEBUG, "WPS: Manufacturer", str, str_len);
 
 	os_free(dev->manufacturer);
-	dev->manufacturer = os_malloc(str_len + 1);
+	dev->manufacturer = dup_binstr(str, str_len);
 	if (dev->manufacturer == NULL)
 		return -1;
-	os_memcpy(dev->manufacturer, str, str_len);
-	dev->manufacturer[str_len] = '\0';
 
 	return 0;
 }
@@ -278,11 +276,9 @@ static int wps_process_model_name(struct wps_device_data *dev, const u8 *str,
 	wpa_hexdump_ascii(MSG_DEBUG, "WPS: Model Name", str, str_len);
 
 	os_free(dev->model_name);
-	dev->model_name = os_malloc(str_len + 1);
+	dev->model_name = dup_binstr(str, str_len);
 	if (dev->model_name == NULL)
 		return -1;
-	os_memcpy(dev->model_name, str, str_len);
-	dev->model_name[str_len] = '\0';
 
 	return 0;
 }
@@ -299,11 +295,9 @@ static int wps_process_model_number(struct wps_device_data *dev, const u8 *str,
 	wpa_hexdump_ascii(MSG_DEBUG, "WPS: Model Number", str, str_len);
 
 	os_free(dev->model_number);
-	dev->model_number = os_malloc(str_len + 1);
+	dev->model_number = dup_binstr(str, str_len);
 	if (dev->model_number == NULL)
 		return -1;
-	os_memcpy(dev->model_number, str, str_len);
-	dev->model_number[str_len] = '\0';
 
 	return 0;
 }
@@ -320,11 +314,9 @@ static int wps_process_serial_number(struct wps_device_data *dev,
 	wpa_hexdump_ascii(MSG_DEBUG, "WPS: Serial Number", str, str_len);
 
 	os_free(dev->serial_number);
-	dev->serial_number = os_malloc(str_len + 1);
+	dev->serial_number = dup_binstr(str, str_len);
 	if (dev->serial_number == NULL)
 		return -1;
-	os_memcpy(dev->serial_number, str, str_len);
-	dev->serial_number[str_len] = '\0';
 
 	return 0;
 }
@@ -341,11 +333,9 @@ static int wps_process_dev_name(struct wps_device_data *dev, const u8 *str,
 	wpa_hexdump_ascii(MSG_DEBUG, "WPS: Device Name", str, str_len);
 
 	os_free(dev->device_name);
-	dev->device_name = os_malloc(str_len + 1);
+	dev->device_name = dup_binstr(str, str_len);
 	if (dev->device_name == NULL)
 		return -1;
-	os_memcpy(dev->device_name, str, str_len);
-	dev->device_name[str_len] = '\0';
 
 	return 0;
 }

+ 9 - 30
src/wps/wps_er.c

@@ -796,52 +796,31 @@ static struct wps_er_sta * wps_er_add_sta_data(struct wps_er_ap *ap,
 
 	if (attr->manufacturer) {
 		os_free(sta->manufacturer);
-		sta->manufacturer = os_malloc(attr->manufacturer_len + 1);
-		if (sta->manufacturer) {
-			os_memcpy(sta->manufacturer, attr->manufacturer,
-				  attr->manufacturer_len);
-			sta->manufacturer[attr->manufacturer_len] = '\0';
-		}
+		sta->manufacturer = dup_binstr(attr->manufacturer,
+					       attr->manufacturer_len);
 	}
 
 	if (attr->model_name) {
 		os_free(sta->model_name);
-		sta->model_name = os_malloc(attr->model_name_len + 1);
-		if (sta->model_name) {
-			os_memcpy(sta->model_name, attr->model_name,
-				  attr->model_name_len);
-			sta->model_name[attr->model_name_len] = '\0';
-		}
+		sta->model_name = dup_binstr(attr->model_name,
+					     attr->model_name_len);
 	}
 
 	if (attr->model_number) {
 		os_free(sta->model_number);
-		sta->model_number = os_malloc(attr->model_number_len + 1);
-		if (sta->model_number) {
-			os_memcpy(sta->model_number, attr->model_number,
-				  attr->model_number_len);
-			sta->model_number[attr->model_number_len] = '\0';
-		}
+		sta->model_number = dup_binstr(attr->model_number,
+					       attr->model_number_len);
 	}
 
 	if (attr->serial_number) {
 		os_free(sta->serial_number);
-		sta->serial_number = os_malloc(attr->serial_number_len + 1);
-		if (sta->serial_number) {
-			os_memcpy(sta->serial_number, attr->serial_number,
-				  attr->serial_number_len);
-			sta->serial_number[attr->serial_number_len] = '\0';
-		}
+		sta->serial_number = dup_binstr(attr->serial_number,
+						attr->serial_number_len);
 	}
 
 	if (attr->dev_name) {
 		os_free(sta->dev_name);
-		sta->dev_name = os_malloc(attr->dev_name_len + 1);
-		if (sta->dev_name) {
-			os_memcpy(sta->dev_name, attr->dev_name,
-				  attr->dev_name_len);
-			sta->dev_name[attr->dev_name_len] = '\0';
-		}
+		sta->dev_name = dup_binstr(attr->dev_name, attr->dev_name_len);
 	}
 
 	eloop_cancel_timeout(wps_er_sta_timeout, sta, NULL);

+ 1 - 3
src/wps/wps_upnp.c

@@ -322,11 +322,9 @@ static void subscr_addr_add_url(struct subscription *s, const char *url,
 	url_len -= 7;
 
 	/* Make a copy of the string to allow modification during parsing */
-	scratch_mem = os_malloc(url_len + 1);
+	scratch_mem = dup_binstr(url, url_len);
 	if (scratch_mem == NULL)
 		goto fail;
-	os_memcpy(scratch_mem, url, url_len);
-	scratch_mem[url_len] = '\0';
 	wpa_printf(MSG_DEBUG, "WPS UPnP: Adding URL '%s'", scratch_mem);
 	host = scratch_mem;
 	path = os_strchr(host, '/');

+ 1 - 3
src/wps/wps_upnp_web.c

@@ -996,13 +996,11 @@ static void web_connection_parse_subscribe(struct upnp_wps_device_sm *sm,
 				h++;
 			len = end - h;
 			os_free(callback_urls);
-			callback_urls = os_malloc(len + 1);
+			callback_urls = dup_binstr(h, len);
 			if (callback_urls == NULL) {
 				ret = HTTP_INTERNAL_SERVER_ERROR;
 				goto error;
 			}
-			os_memcpy(callback_urls, h, len);
-			callback_urls[len] = 0;
 			continue;
 		}
 		/* SID is only for renewal */

+ 1 - 3
wpa_supplicant/config.c

@@ -322,11 +322,9 @@ static int wpa_config_parse_psk(const struct parse_data *data,
 			return 0;
 		ssid->psk_set = 0;
 		os_free(ssid->passphrase);
-		ssid->passphrase = os_malloc(len + 1);
+		ssid->passphrase = dup_binstr(value, len);
 		if (ssid->passphrase == NULL)
 			return -1;
-		os_memcpy(ssid->passphrase, value, len);
-		ssid->passphrase[len] = '\0';
 		return 0;
 #else /* CONFIG_NO_PBKDF2 */
 		wpa_printf(MSG_ERROR, "Line %d: ASCII passphrase not "

+ 1 - 3
wpa_supplicant/interworking.c

@@ -408,11 +408,9 @@ static const u8 * nai_realm_parse_realm(struct nai_realm *r, const u8 *pos,
 		return NULL;
 	}
 	wpa_hexdump_ascii(MSG_DEBUG, "NAI Realm", pos, realm_len);
-	r->realm = os_malloc(realm_len + 1);
+	r->realm = dup_binstr(pos, realm_len);
 	if (r->realm == NULL)
 		return NULL;
-	os_memcpy(r->realm, pos, realm_len);
-	r->realm[realm_len] = '\0';
 	pos += realm_len;
 
 	if (pos + 1 > f_end) {

+ 2 - 6
wpa_supplicant/wpa_cli.c

@@ -173,11 +173,9 @@ static void cli_txt_list_del_word(struct dl_list *txt_list, const char *txt)
 	end = os_strchr(txt, ' ');
 	if (end == NULL)
 		end = txt + os_strlen(txt);
-	buf = os_malloc(end - txt + 1);
+	buf = dup_binstr(txt, end - txt);
 	if (buf == NULL)
 		return;
-	os_memcpy(buf, txt, end - txt);
-	buf[end - txt] = '\0';
 	cli_txt_list_del(txt_list, buf);
 	os_free(buf);
 }
@@ -223,11 +221,9 @@ static int cli_txt_list_add_word(struct dl_list *txt_list, const char *txt)
 	end = os_strchr(txt, ' ');
 	if (end == NULL)
 		end = txt + os_strlen(txt);
-	buf = os_malloc(end - txt + 1);
+	buf = dup_binstr(txt, end - txt);
 	if (buf == NULL)
 		return -1;
-	os_memcpy(buf, txt, end - txt);
-	buf[end - txt] = '\0';
 	ret = cli_txt_list_add(txt_list, buf);
 	os_free(buf);
 	return ret;

+ 1 - 3
wpa_supplicant/wpa_priv.c

@@ -573,13 +573,11 @@ wpa_priv_interface_init(const char *dir, const char *params)
 	iface->fd = -1;
 
 	len = pos - params;
-	iface->driver_name = os_malloc(len + 1);
+	iface->driver_name = dup_binstr(params, len);
 	if (iface->driver_name == NULL) {
 		wpa_priv_interface_deinit(iface);
 		return NULL;
 	}
-	os_memcpy(iface->driver_name, params, len);
-	iface->driver_name[len] = '\0';
 
 	for (i = 0; wpa_drivers[i]; i++) {
 		if (os_strcmp(iface->driver_name,