From 5e24dc8a4bc8297dee3b95594457a51d36fde00d Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Sat, 27 Apr 2013 23:44:59 +0300 Subject: [PATCH] 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 --- src/ap/ieee802_1x.c | 9 ++------ src/drivers/driver_ndis.c | 16 ++------------ src/drivers/driver_wext.c | 4 +--- src/eap_peer/eap_mschapv2.c | 4 +--- src/eap_peer/tncc.c | 4 +--- src/eap_server/eap_sim_db.c | 9 +------- src/eap_server/tncs.c | 4 +--- src/tls/x509v3.c | 5 ++--- src/utils/common.c | 24 +++++++++++++++------ src/utils/common.h | 1 + src/wps/wps_dev_attr.c | 20 +++++------------- src/wps/wps_er.c | 39 ++++++++--------------------------- src/wps/wps_upnp.c | 4 +--- src/wps/wps_upnp_web.c | 4 +--- wpa_supplicant/config.c | 4 +--- wpa_supplicant/interworking.c | 4 +--- wpa_supplicant/wpa_cli.c | 8 ++----- wpa_supplicant/wpa_priv.c | 4 +--- 18 files changed, 51 insertions(+), 116 deletions(-) diff --git a/src/ap/ieee802_1x.c b/src/ap/ieee802_1x.c index d9c21a8b8..cc5f83c8f 100644 --- a/src/ap/ieee802_1x.c +++ b/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'", diff --git a/src/drivers/driver_ndis.c b/src/drivers/driver_ndis.c index 7af331777..4656c1b77 100644 --- a/src/drivers/driver_ndis.c +++ b/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; diff --git a/src/drivers/driver_wext.c b/src/drivers/driver_wext.c index 9733e0156..140105024 100644 --- a/src/drivers/driver_wext.c +++ b/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; diff --git a/src/eap_peer/eap_mschapv2.c b/src/eap_peer/eap_mschapv2.c index fb6c282a1..f9aa74257 100644 --- a/src/eap_peer/eap_mschapv2.c +++ b/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); } diff --git a/src/eap_peer/tncc.c b/src/eap_peer/tncc.c index f5edfd52c..a3ec39514 100644 --- a/src/eap_peer/tncc.c +++ b/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, ""); if (start == NULL || end == NULL || start > end) { diff --git a/src/eap_server/eap_sim_db.c b/src/eap_server/eap_sim_db.c index 257013e3e..1b9d701e0 100644 --- a/src/eap_server/eap_sim_db.c +++ b/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); } diff --git a/src/eap_server/tncs.c b/src/eap_server/tncs.c index 5e332ae02..e429f1e67 100644 --- a/src/eap_server/tncs.c +++ b/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, ""); if (start == NULL || end == NULL || start > end) { diff --git a/src/tls/x509v3.c b/src/tls/x509v3.c index 87c51784e..06540bffd 100644 --- a/src/tls/x509v3.c +++ b/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; } diff --git a/src/utils/common.c b/src/utils/common.c index e63698491..bf326cdb6 100644 --- a/src/utils/common.c +++ b/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; +} diff --git a/src/utils/common.h b/src/utils/common.h index a859042a7..e4f703130 100644 --- a/src/utils/common.h +++ b/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) { diff --git a/src/wps/wps_dev_attr.c b/src/wps/wps_dev_attr.c index 3c94a4346..7a7c09993 100644 --- a/src/wps/wps_dev_attr.c +++ b/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; } diff --git a/src/wps/wps_er.c b/src/wps/wps_er.c index 14c1b779d..18df20b39 100644 --- a/src/wps/wps_er.c +++ b/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); diff --git a/src/wps/wps_upnp.c b/src/wps/wps_upnp.c index 09a46a215..af63e4db4 100644 --- a/src/wps/wps_upnp.c +++ b/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, '/'); diff --git a/src/wps/wps_upnp_web.c b/src/wps/wps_upnp_web.c index ce0bede83..11386d882 100644 --- a/src/wps/wps_upnp_web.c +++ b/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 */ diff --git a/wpa_supplicant/config.c b/wpa_supplicant/config.c index 0d988840d..2de784509 100644 --- a/wpa_supplicant/config.c +++ b/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 " diff --git a/wpa_supplicant/interworking.c b/wpa_supplicant/interworking.c index b59dd6aba..e35628b22 100644 --- a/wpa_supplicant/interworking.c +++ b/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) { diff --git a/wpa_supplicant/wpa_cli.c b/wpa_supplicant/wpa_cli.c index e700d7ea4..bd84a19c9 100644 --- a/wpa_supplicant/wpa_cli.c +++ b/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; diff --git a/wpa_supplicant/wpa_priv.c b/wpa_supplicant/wpa_priv.c index ad6a080b9..4afaae904 100644 --- a/wpa_supplicant/wpa_priv.c +++ b/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,