[Secure-testing-team] Bug#504696: ndiswrapper-source: longs ESSIDs can expose security vulnerability

Kel Modderman kel at otaku42.de
Thu Nov 6 10:48:42 UTC 2008


Package: ndiswrapper-source
Version: 1.53-1
Severity: grave
Tags: security patch
Justification: user security hole

>From [0]:
Anders Kaseorg discovered that ndiswrapper did not correctly handle long
ESSIDs. For a system using ndiswrapper, a physically near-by attacker could
generate specially crafted wireless network traffic and execute arbitrary
code with root privileges. (CVE-2008-4395 [1])

Attached is the diff contrinuted by Anders Kaseorg to [2].

[0] http://www.ubuntu.com/usn/usn-662-1
[1] http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2008-4395
[2] https://bugs.launchpad.net/ubuntu/+source/linux/+bug/275860

Thanks, Kel.
---
diff --git a/ubuntu/ndiswrapper/iw_ndis.c b/ubuntu/ndiswrapper/iw_ndis.c
index b114ef6..01d3751 100644
--- a/ubuntu/ndiswrapper/iw_ndis.c
+++ b/ubuntu/ndiswrapper/iw_ndis.c
@@ -47,12 +47,7 @@ int set_essid(struct ndis_device *wnd, const char *ssid, int ssid_len)
 	req.length = ssid_len;
 	if (ssid_len)
 		memcpy(&req.essid, ssid, ssid_len);
-	DBG_BLOCK(2) {
-		char buf[NDIS_ESSID_MAX_SIZE+1];
-		memcpy(buf, ssid, ssid_len);
-		buf[ssid_len] = 0;
-		TRACE2("ssid = '%s'", buf);
-	}
+	TRACE2("ssid = '%.*s'", ssid_len, ssid);
 
 	res = mp_set(wnd, OID_802_11_SSID, &req, sizeof(req));
 	if (res) {
@@ -125,7 +120,6 @@ static int iw_get_essid(struct net_device *dev, struct iw_request_info *info,
 		EXIT2(return -EOPNOTSUPP);
 	}
 	memcpy(extra, req.essid, req.length);
-	extra[req.length] = 0;
 	if (req.length > 0)
 		wrqu->essid.flags  = 1;
 	else
@@ -1000,7 +994,7 @@ static int iw_set_nick(struct net_device *dev, struct iw_request_info *info,
 
 	if (wrqu->data.length > IW_ESSID_MAX_SIZE || wrqu->data.length <= 0)
 		return -EINVAL;
-	memset(wnd->nick, 0, sizeof(wnd->nick));
+	wnd->nick_len = wrqu->data.length;
 	memcpy(wnd->nick, extra, wrqu->data.length);
 	return 0;
 }
@@ -1010,7 +1004,7 @@ static int iw_get_nick(struct net_device *dev, struct iw_request_info *info,
 {
 	struct ndis_device *wnd = netdev_priv(dev);
 
-	wrqu->data.length = strlen(wnd->nick);
+	wrqu->data.length = wnd->nick_len;
 	memcpy(extra, wnd->nick, wrqu->data.length);
 	return 0;
 }
diff --git a/ubuntu/ndiswrapper/ndis.h b/ubuntu/ndiswrapper/ndis.h
index 27ba99e..65d6b0b 100644
--- a/ubuntu/ndiswrapper/ndis.h
+++ b/ubuntu/ndiswrapper/ndis.h
@@ -878,6 +878,7 @@ struct ndis_device {
 	unsigned long scan_timestamp;
 	struct encr_info encr_info;
 	char nick[IW_ESSID_MAX_SIZE];
+	size_t nick_len;
 	struct ndis_essid essid;
 	struct auth_encr_capa capa;
 	enum ndis_infrastructure_mode infrastructure_mode;
diff --git a/ubuntu/ndiswrapper/proc.c b/ubuntu/ndiswrapper/proc.c
index fd5f433..6feff23 100644
--- a/ubuntu/ndiswrapper/proc.c
+++ b/ubuntu/ndiswrapper/proc.c
@@ -97,10 +97,8 @@ static int procfs_read_ndis_encr(char *page, char **start, off_t off,
 	p += sprintf(p, "\n");
 
 	res = mp_query(wnd, OID_802_11_SSID, &essid, sizeof(essid));
-	if (!res) {
-		essid.essid[essid.length] = '\0';
-		p += sprintf(p, "essid=%s\n", essid.essid);
-	}
+	if (!res)
+		p += sprintf(p, "essid=%.*s\n", essid.length, essid.essid);
 	res = mp_query_int(wnd, OID_802_11_ENCRYPTION_STATUS, &encr_status);
 	if (!res) {
 		typeof(&wnd->encr_info.keys[0]) tx_key;
diff --git a/ubuntu/ndiswrapper/wrapndis.c b/ubuntu/ndiswrapper/wrapndis.c
index f6e5d46..35ef1cd 100644
--- a/ubuntu/ndiswrapper/wrapndis.c
+++ b/ubuntu/ndiswrapper/wrapndis.c
@@ -2028,7 +2028,7 @@ static wstdcall NTSTATUS NdisAddDevice(struct driver_object *drv_obj,
 	wnd->attributes = 0;
 	wnd->dma_map_count = 0;
 	wnd->dma_map_addr = NULL;
-	wnd->nick[0] = 0;
+	wnd->nick_len = 0;
 	init_timer(&wnd->hangcheck_timer);
 	wnd->scan_timestamp = 0;
 	init_timer(&wnd->iw_stats_timer);
---





More information about the Secure-testing-team mailing list