Kel Modderman
2008-Nov-06 10:48 UTC
[Secure-testing-team] Bug#504696: ndiswrapper-source: longs ESSIDs can expose security vulnerability
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); ---