提交 c2805fbb 编写于 作者: J Jean Tourrilhes 提交者: John W. Linville

[PATCH] WE-22 : prevent information leak on 64 bit

 	Johannes Berg discovered that kernel space was leaking to
userspace on 64 bit platform. He made a first patch to fix that. This
is an improved version of his patch.
Signed-off-by: NJean Tourrilhes <jt@hpl.hp.com>
Signed-off-by: NJohn W. Linville <linville@tuxdriver.com>
上级 ed4bb106
/* /*
* This file define a set of standard wireless extensions * This file define a set of standard wireless extensions
* *
* Version : 21 14.3.06 * Version : 22 16.3.07
* *
* Authors : Jean Tourrilhes - HPL - <jt@hpl.hp.com> * Authors : Jean Tourrilhes - HPL - <jt@hpl.hp.com>
* Copyright (c) 1997-2006 Jean Tourrilhes, All Rights Reserved. * Copyright (c) 1997-2007 Jean Tourrilhes, All Rights Reserved.
*/ */
#ifndef _LINUX_WIRELESS_H #ifndef _LINUX_WIRELESS_H
...@@ -85,7 +85,7 @@ ...@@ -85,7 +85,7 @@
* (there is some stuff that will be added in the future...) * (there is some stuff that will be added in the future...)
* I just plan to increment with each new version. * I just plan to increment with each new version.
*/ */
#define WIRELESS_EXT 21 #define WIRELESS_EXT 22
/* /*
* Changes : * Changes :
...@@ -221,6 +221,10 @@ ...@@ -221,6 +221,10 @@
* - Add IW_RETRY_SHORT/IW_RETRY_LONG retry modifiers * - Add IW_RETRY_SHORT/IW_RETRY_LONG retry modifiers
* - Power/Retry relative values no longer * 100000 * - Power/Retry relative values no longer * 100000
* - Add explicit flag to tell stats are in 802.11k RCPI : IW_QUAL_RCPI * - Add explicit flag to tell stats are in 802.11k RCPI : IW_QUAL_RCPI
*
* V21 to V22
* ----------
* - Prevent leaking of kernel space in stream on 64 bits.
*/ */
/**************************** CONSTANTS ****************************/ /**************************** CONSTANTS ****************************/
...@@ -1085,4 +1089,15 @@ struct iw_event ...@@ -1085,4 +1089,15 @@ struct iw_event
#define IW_EV_POINT_LEN (IW_EV_LCP_LEN + sizeof(struct iw_point) - \ #define IW_EV_POINT_LEN (IW_EV_LCP_LEN + sizeof(struct iw_point) - \
IW_EV_POINT_OFF) IW_EV_POINT_OFF)
/* Size of the Event prefix when packed in stream */
#define IW_EV_LCP_PK_LEN (4)
/* Size of the various events when packed in stream */
#define IW_EV_CHAR_PK_LEN (IW_EV_LCP_PK_LEN + IFNAMSIZ)
#define IW_EV_UINT_PK_LEN (IW_EV_LCP_PK_LEN + sizeof(__u32))
#define IW_EV_FREQ_PK_LEN (IW_EV_LCP_PK_LEN + sizeof(struct iw_freq))
#define IW_EV_PARAM_PK_LEN (IW_EV_LCP_PK_LEN + sizeof(struct iw_param))
#define IW_EV_ADDR_PK_LEN (IW_EV_LCP_PK_LEN + sizeof(struct sockaddr))
#define IW_EV_QUAL_PK_LEN (IW_EV_LCP_PK_LEN + sizeof(struct iw_quality))
#define IW_EV_POINT_PK_LEN (IW_EV_LCP_LEN + 4)
#endif /* _LINUX_WIRELESS_H */ #endif /* _LINUX_WIRELESS_H */
/* /*
* This file define the new driver API for Wireless Extensions * This file define the new driver API for Wireless Extensions
* *
* Version : 7 18.3.05 * Version : 8 16.3.07
* *
* Authors : Jean Tourrilhes - HPL - <jt@hpl.hp.com> * Authors : Jean Tourrilhes - HPL - <jt@hpl.hp.com>
* Copyright (c) 2001-2006 Jean Tourrilhes, All Rights Reserved. * Copyright (c) 2001-2007 Jean Tourrilhes, All Rights Reserved.
*/ */
#ifndef _IW_HANDLER_H #ifndef _IW_HANDLER_H
...@@ -207,7 +207,7 @@ ...@@ -207,7 +207,7 @@
* will be needed... * will be needed...
* I just plan to increment with each new version. * I just plan to increment with each new version.
*/ */
#define IW_HANDLER_VERSION 7 #define IW_HANDLER_VERSION 8
/* /*
* Changes : * Changes :
...@@ -239,6 +239,10 @@ ...@@ -239,6 +239,10 @@
* - Remove (struct iw_point *)->pointer from events and streams * - Remove (struct iw_point *)->pointer from events and streams
* - Remove spy_offset from struct iw_handler_def * - Remove spy_offset from struct iw_handler_def
* - Add "check" version of event macros for ieee802.11 stack * - Add "check" version of event macros for ieee802.11 stack
*
* V7 to V8
* ----------
* - Prevent leaking of kernel space in stream on 64 bits.
*/ */
/**************************** CONSTANTS ****************************/ /**************************** CONSTANTS ****************************/
...@@ -500,7 +504,11 @@ iwe_stream_add_event(char * stream, /* Stream of events */ ...@@ -500,7 +504,11 @@ iwe_stream_add_event(char * stream, /* Stream of events */
/* Check if it's possible */ /* Check if it's possible */
if(likely((stream + event_len) < ends)) { if(likely((stream + event_len) < ends)) {
iwe->len = event_len; iwe->len = event_len;
memcpy(stream, (char *) iwe, event_len); /* Beware of alignement issues on 64 bits */
memcpy(stream, (char *) iwe, IW_EV_LCP_PK_LEN);
memcpy(stream + IW_EV_LCP_LEN,
((char *) iwe) + IW_EV_LCP_LEN,
event_len - IW_EV_LCP_LEN);
stream += event_len; stream += event_len;
} }
return stream; return stream;
...@@ -521,10 +529,10 @@ iwe_stream_add_point(char * stream, /* Stream of events */ ...@@ -521,10 +529,10 @@ iwe_stream_add_point(char * stream, /* Stream of events */
/* Check if it's possible */ /* Check if it's possible */
if(likely((stream + event_len) < ends)) { if(likely((stream + event_len) < ends)) {
iwe->len = event_len; iwe->len = event_len;
memcpy(stream, (char *) iwe, IW_EV_LCP_LEN); memcpy(stream, (char *) iwe, IW_EV_LCP_PK_LEN);
memcpy(stream + IW_EV_LCP_LEN, memcpy(stream + IW_EV_LCP_LEN,
((char *) iwe) + IW_EV_LCP_LEN + IW_EV_POINT_OFF, ((char *) iwe) + IW_EV_LCP_LEN + IW_EV_POINT_OFF,
IW_EV_POINT_LEN - IW_EV_LCP_LEN); IW_EV_POINT_PK_LEN - IW_EV_LCP_PK_LEN);
memcpy(stream + IW_EV_POINT_LEN, extra, iwe->u.data.length); memcpy(stream + IW_EV_POINT_LEN, extra, iwe->u.data.length);
stream += event_len; stream += event_len;
} }
...@@ -574,7 +582,11 @@ iwe_stream_check_add_event(char * stream, /* Stream of events */ ...@@ -574,7 +582,11 @@ iwe_stream_check_add_event(char * stream, /* Stream of events */
/* Check if it's possible, set error if not */ /* Check if it's possible, set error if not */
if(likely((stream + event_len) < ends)) { if(likely((stream + event_len) < ends)) {
iwe->len = event_len; iwe->len = event_len;
memcpy(stream, (char *) iwe, event_len); /* Beware of alignement issues on 64 bits */
memcpy(stream, (char *) iwe, IW_EV_LCP_PK_LEN);
memcpy(stream + IW_EV_LCP_LEN,
((char *) iwe) + IW_EV_LCP_LEN,
event_len - IW_EV_LCP_LEN);
stream += event_len; stream += event_len;
} else } else
*perr = -E2BIG; *perr = -E2BIG;
...@@ -598,10 +610,10 @@ iwe_stream_check_add_point(char * stream, /* Stream of events */ ...@@ -598,10 +610,10 @@ iwe_stream_check_add_point(char * stream, /* Stream of events */
/* Check if it's possible */ /* Check if it's possible */
if(likely((stream + event_len) < ends)) { if(likely((stream + event_len) < ends)) {
iwe->len = event_len; iwe->len = event_len;
memcpy(stream, (char *) iwe, IW_EV_LCP_LEN); memcpy(stream, (char *) iwe, IW_EV_LCP_PK_LEN);
memcpy(stream + IW_EV_LCP_LEN, memcpy(stream + IW_EV_LCP_LEN,
((char *) iwe) + IW_EV_LCP_LEN + IW_EV_POINT_OFF, ((char *) iwe) + IW_EV_LCP_LEN + IW_EV_POINT_OFF,
IW_EV_POINT_LEN - IW_EV_LCP_LEN); IW_EV_POINT_PK_LEN - IW_EV_LCP_PK_LEN);
memcpy(stream + IW_EV_POINT_LEN, extra, iwe->u.data.length); memcpy(stream + IW_EV_POINT_LEN, extra, iwe->u.data.length);
stream += event_len; stream += event_len;
} else } else
......
...@@ -621,7 +621,8 @@ static int rtnl_getlink(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg) ...@@ -621,7 +621,8 @@ static int rtnl_getlink(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg)
if (err < 0) if (err < 0)
goto errout; goto errout;
iw += IW_EV_POINT_OFF; /* Payload is at an offset in buffer */
iw = iw_buf + IW_EV_POINT_OFF;
} }
#endif /* CONFIG_NET_WIRELESS_RTNETLINK */ #endif /* CONFIG_NET_WIRELESS_RTNETLINK */
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* This file implement the Wireless Extensions APIs. * This file implement the Wireless Extensions APIs.
* *
* Authors : Jean Tourrilhes - HPL - <jt@hpl.hp.com> * Authors : Jean Tourrilhes - HPL - <jt@hpl.hp.com>
* Copyright (c) 1997-2006 Jean Tourrilhes, All Rights Reserved. * Copyright (c) 1997-2007 Jean Tourrilhes, All Rights Reserved.
* *
* (As all part of the Linux kernel, this file is GPL) * (As all part of the Linux kernel, this file is GPL)
*/ */
...@@ -76,6 +76,9 @@ ...@@ -76,6 +76,9 @@
* o Change length in ESSID and NICK to strlen() instead of strlen()+1 * o Change length in ESSID and NICK to strlen() instead of strlen()+1
* o Make standard_ioctl_num and standard_event_num unsigned * o Make standard_ioctl_num and standard_event_num unsigned
* o Remove (struct net_device *)->get_wireless_stats() * o Remove (struct net_device *)->get_wireless_stats()
*
* v10 - 16.3.07 - Jean II
* o Prevent leaking of kernel space in stream on 64 bits.
*/ */
/***************************** INCLUDES *****************************/ /***************************** INCLUDES *****************************/
...@@ -427,6 +430,21 @@ static const int event_type_size[] = { ...@@ -427,6 +430,21 @@ static const int event_type_size[] = {
IW_EV_QUAL_LEN, /* IW_HEADER_TYPE_QUAL */ IW_EV_QUAL_LEN, /* IW_HEADER_TYPE_QUAL */
}; };
/* Size (in bytes) of various events, as packed */
static const int event_type_pk_size[] = {
IW_EV_LCP_PK_LEN, /* IW_HEADER_TYPE_NULL */
0,
IW_EV_CHAR_PK_LEN, /* IW_HEADER_TYPE_CHAR */
0,
IW_EV_UINT_PK_LEN, /* IW_HEADER_TYPE_UINT */
IW_EV_FREQ_PK_LEN, /* IW_HEADER_TYPE_FREQ */
IW_EV_ADDR_PK_LEN, /* IW_HEADER_TYPE_ADDR */
0,
IW_EV_POINT_PK_LEN, /* Without variable payload */
IW_EV_PARAM_PK_LEN, /* IW_HEADER_TYPE_PARAM */
IW_EV_QUAL_PK_LEN, /* IW_HEADER_TYPE_QUAL */
};
/************************ COMMON SUBROUTINES ************************/ /************************ COMMON SUBROUTINES ************************/
/* /*
* Stuff that may be used in various place or doesn't fit in one * Stuff that may be used in various place or doesn't fit in one
...@@ -1217,7 +1235,7 @@ static int rtnetlink_standard_get(struct net_device * dev, ...@@ -1217,7 +1235,7 @@ static int rtnetlink_standard_get(struct net_device * dev,
memcpy(buffer + IW_EV_POINT_OFF, request, request_len); memcpy(buffer + IW_EV_POINT_OFF, request, request_len);
/* Use our own copy of wrqu */ /* Use our own copy of wrqu */
wrqu = (union iwreq_data *) (buffer + IW_EV_POINT_OFF wrqu = (union iwreq_data *) (buffer + IW_EV_POINT_OFF
+ IW_EV_LCP_LEN); + IW_EV_LCP_PK_LEN);
/* No extra arguments. Trivial to handle */ /* No extra arguments. Trivial to handle */
ret = handler(dev, &info, wrqu, NULL); ret = handler(dev, &info, wrqu, NULL);
...@@ -1229,8 +1247,8 @@ static int rtnetlink_standard_get(struct net_device * dev, ...@@ -1229,8 +1247,8 @@ static int rtnetlink_standard_get(struct net_device * dev,
/* Get a temp copy of wrqu (skip pointer) */ /* Get a temp copy of wrqu (skip pointer) */
memcpy(((char *) &wrqu_point) + IW_EV_POINT_OFF, memcpy(((char *) &wrqu_point) + IW_EV_POINT_OFF,
((char *) request) + IW_EV_LCP_LEN, ((char *) request) + IW_EV_LCP_PK_LEN,
IW_EV_POINT_LEN - IW_EV_LCP_LEN); IW_EV_POINT_LEN - IW_EV_LCP_PK_LEN);
/* Calculate space needed by arguments. Always allocate /* Calculate space needed by arguments. Always allocate
* for max space. Easier, and won't last long... */ * for max space. Easier, and won't last long... */
...@@ -1240,7 +1258,7 @@ static int rtnetlink_standard_get(struct net_device * dev, ...@@ -1240,7 +1258,7 @@ static int rtnetlink_standard_get(struct net_device * dev,
(wrqu_point.data.length > descr->max_tokens)) (wrqu_point.data.length > descr->max_tokens))
extra_size = (wrqu_point.data.length extra_size = (wrqu_point.data.length
* descr->token_size); * descr->token_size);
buffer_size = extra_size + IW_EV_POINT_LEN + IW_EV_POINT_OFF; buffer_size = extra_size + IW_EV_POINT_PK_LEN + IW_EV_POINT_OFF;
#ifdef WE_RTNETLINK_DEBUG #ifdef WE_RTNETLINK_DEBUG
printk(KERN_DEBUG "%s (WE.r) : Malloc %d bytes (%d bytes)\n", printk(KERN_DEBUG "%s (WE.r) : Malloc %d bytes (%d bytes)\n",
dev->name, extra_size, buffer_size); dev->name, extra_size, buffer_size);
...@@ -1254,15 +1272,15 @@ static int rtnetlink_standard_get(struct net_device * dev, ...@@ -1254,15 +1272,15 @@ static int rtnetlink_standard_get(struct net_device * dev,
/* Put wrqu in the right place (just before extra). /* Put wrqu in the right place (just before extra).
* Leave space for IWE header and dummy pointer... * Leave space for IWE header and dummy pointer...
* Note that IW_EV_LCP_LEN==4 bytes, so it's still aligned... * Note that IW_EV_LCP_PK_LEN==4 bytes, so it's still aligned.
*/ */
memcpy(buffer + IW_EV_LCP_LEN + IW_EV_POINT_OFF, memcpy(buffer + IW_EV_LCP_PK_LEN + IW_EV_POINT_OFF,
((char *) &wrqu_point) + IW_EV_POINT_OFF, ((char *) &wrqu_point) + IW_EV_POINT_OFF,
IW_EV_POINT_LEN - IW_EV_LCP_LEN); IW_EV_POINT_PK_LEN - IW_EV_LCP_PK_LEN);
wrqu = (union iwreq_data *) (buffer + IW_EV_LCP_LEN); wrqu = (union iwreq_data *) (buffer + IW_EV_LCP_PK_LEN);
/* Extra comes logically after that. Offset +12 bytes. */ /* Extra comes logically after that. Offset +12 bytes. */
extra = buffer + IW_EV_POINT_OFF + IW_EV_POINT_LEN; extra = buffer + IW_EV_POINT_OFF + IW_EV_POINT_PK_LEN;
/* Call the handler */ /* Call the handler */
ret = handler(dev, &info, wrqu, extra); ret = handler(dev, &info, wrqu, extra);
...@@ -1270,11 +1288,11 @@ static int rtnetlink_standard_get(struct net_device * dev, ...@@ -1270,11 +1288,11 @@ static int rtnetlink_standard_get(struct net_device * dev,
/* Calculate real returned length */ /* Calculate real returned length */
extra_size = (wrqu->data.length * descr->token_size); extra_size = (wrqu->data.length * descr->token_size);
/* Re-adjust reply size */ /* Re-adjust reply size */
request->len = extra_size + IW_EV_POINT_LEN; request->len = extra_size + IW_EV_POINT_PK_LEN;
/* Put the iwe header where it should, i.e. scrap the /* Put the iwe header where it should, i.e. scrap the
* dummy pointer. */ * dummy pointer. */
memcpy(buffer + IW_EV_POINT_OFF, request, IW_EV_LCP_LEN); memcpy(buffer + IW_EV_POINT_OFF, request, IW_EV_LCP_PK_LEN);
#ifdef WE_RTNETLINK_DEBUG #ifdef WE_RTNETLINK_DEBUG
printk(KERN_DEBUG "%s (WE.r) : Reply 0x%04X, hdr_len %d, tokens %d, extra_size %d, buffer_size %d\n", dev->name, cmd, hdr_len, wrqu->data.length, extra_size, buffer_size); printk(KERN_DEBUG "%s (WE.r) : Reply 0x%04X, hdr_len %d, tokens %d, extra_size %d, buffer_size %d\n", dev->name, cmd, hdr_len, wrqu->data.length, extra_size, buffer_size);
...@@ -1331,10 +1349,10 @@ static inline int rtnetlink_standard_set(struct net_device * dev, ...@@ -1331,10 +1349,10 @@ static inline int rtnetlink_standard_set(struct net_device * dev,
#endif /* WE_RTNETLINK_DEBUG */ #endif /* WE_RTNETLINK_DEBUG */
/* Extract fixed header from request. This is properly aligned. */ /* Extract fixed header from request. This is properly aligned. */
wrqu = &request->u; wrqu = (union iwreq_data *) (((char *) request) + IW_EV_LCP_PK_LEN);
/* Check if wrqu is complete */ /* Check if wrqu is complete */
hdr_len = event_type_size[descr->header_type]; hdr_len = event_type_pk_size[descr->header_type];
if(request_len < hdr_len) { if(request_len < hdr_len) {
#ifdef WE_RTNETLINK_DEBUG #ifdef WE_RTNETLINK_DEBUG
printk(KERN_DEBUG printk(KERN_DEBUG
...@@ -1359,7 +1377,7 @@ static inline int rtnetlink_standard_set(struct net_device * dev, ...@@ -1359,7 +1377,7 @@ static inline int rtnetlink_standard_set(struct net_device * dev,
/* Put wrqu in the right place (skip pointer) */ /* Put wrqu in the right place (skip pointer) */
memcpy(((char *) &wrqu_point) + IW_EV_POINT_OFF, memcpy(((char *) &wrqu_point) + IW_EV_POINT_OFF,
wrqu, IW_EV_POINT_LEN - IW_EV_LCP_LEN); wrqu, IW_EV_POINT_PK_LEN - IW_EV_LCP_PK_LEN);
/* Don't forget about the event code... */ /* Don't forget about the event code... */
wrqu = &wrqu_point; wrqu = &wrqu_point;
...@@ -1483,7 +1501,7 @@ static inline int rtnetlink_private_get(struct net_device * dev, ...@@ -1483,7 +1501,7 @@ static inline int rtnetlink_private_get(struct net_device * dev,
hdr_len = extra_size; hdr_len = extra_size;
extra_size = 0; extra_size = 0;
} else { } else {
hdr_len = IW_EV_POINT_LEN; hdr_len = IW_EV_POINT_PK_LEN;
} }
/* Check if wrqu is complete */ /* Check if wrqu is complete */
...@@ -1514,7 +1532,7 @@ static inline int rtnetlink_private_get(struct net_device * dev, ...@@ -1514,7 +1532,7 @@ static inline int rtnetlink_private_get(struct net_device * dev,
memcpy(buffer + IW_EV_POINT_OFF, request, request_len); memcpy(buffer + IW_EV_POINT_OFF, request, request_len);
/* Use our own copy of wrqu */ /* Use our own copy of wrqu */
wrqu = (union iwreq_data *) (buffer + IW_EV_POINT_OFF wrqu = (union iwreq_data *) (buffer + IW_EV_POINT_OFF
+ IW_EV_LCP_LEN); + IW_EV_LCP_PK_LEN);
/* No extra arguments. Trivial to handle */ /* No extra arguments. Trivial to handle */
ret = handler(dev, &info, wrqu, (char *) wrqu); ret = handler(dev, &info, wrqu, (char *) wrqu);
...@@ -1523,7 +1541,7 @@ static inline int rtnetlink_private_get(struct net_device * dev, ...@@ -1523,7 +1541,7 @@ static inline int rtnetlink_private_get(struct net_device * dev,
char * extra; char * extra;
/* Buffer for full reply */ /* Buffer for full reply */
buffer_size = extra_size + IW_EV_POINT_LEN + IW_EV_POINT_OFF; buffer_size = extra_size + IW_EV_POINT_PK_LEN + IW_EV_POINT_OFF;
#ifdef WE_RTNETLINK_DEBUG #ifdef WE_RTNETLINK_DEBUG
printk(KERN_DEBUG "%s (WE.r) : Malloc %d bytes (%d bytes)\n", printk(KERN_DEBUG "%s (WE.r) : Malloc %d bytes (%d bytes)\n",
...@@ -1538,15 +1556,15 @@ static inline int rtnetlink_private_get(struct net_device * dev, ...@@ -1538,15 +1556,15 @@ static inline int rtnetlink_private_get(struct net_device * dev,
/* Put wrqu in the right place (just before extra). /* Put wrqu in the right place (just before extra).
* Leave space for IWE header and dummy pointer... * Leave space for IWE header and dummy pointer...
* Note that IW_EV_LCP_LEN==4 bytes, so it's still aligned... * Note that IW_EV_LCP_PK_LEN==4 bytes, so it's still aligned.
*/ */
memcpy(buffer + IW_EV_LCP_LEN + IW_EV_POINT_OFF, memcpy(buffer + IW_EV_LCP_PK_LEN + IW_EV_POINT_OFF,
((char *) request) + IW_EV_LCP_LEN, ((char *) request) + IW_EV_LCP_PK_LEN,
IW_EV_POINT_LEN - IW_EV_LCP_LEN); IW_EV_POINT_PK_LEN - IW_EV_LCP_PK_LEN);
wrqu = (union iwreq_data *) (buffer + IW_EV_LCP_LEN); wrqu = (union iwreq_data *) (buffer + IW_EV_LCP_PK_LEN);
/* Extra comes logically after that. Offset +12 bytes. */ /* Extra comes logically after that. Offset +12 bytes. */
extra = buffer + IW_EV_POINT_OFF + IW_EV_POINT_LEN; extra = buffer + IW_EV_POINT_OFF + IW_EV_POINT_PK_LEN;
/* Call the handler */ /* Call the handler */
ret = handler(dev, &info, wrqu, extra); ret = handler(dev, &info, wrqu, extra);
...@@ -1556,11 +1574,11 @@ static inline int rtnetlink_private_get(struct net_device * dev, ...@@ -1556,11 +1574,11 @@ static inline int rtnetlink_private_get(struct net_device * dev,
if (!(descr->get_args & IW_PRIV_SIZE_FIXED)) if (!(descr->get_args & IW_PRIV_SIZE_FIXED))
extra_size = adjust_priv_size(descr->get_args, wrqu); extra_size = adjust_priv_size(descr->get_args, wrqu);
/* Re-adjust reply size */ /* Re-adjust reply size */
request->len = extra_size + IW_EV_POINT_LEN; request->len = extra_size + IW_EV_POINT_PK_LEN;
/* Put the iwe header where it should, i.e. scrap the /* Put the iwe header where it should, i.e. scrap the
* dummy pointer. */ * dummy pointer. */
memcpy(buffer + IW_EV_POINT_OFF, request, IW_EV_LCP_LEN); memcpy(buffer + IW_EV_POINT_OFF, request, IW_EV_LCP_PK_LEN);
#ifdef WE_RTNETLINK_DEBUG #ifdef WE_RTNETLINK_DEBUG
printk(KERN_DEBUG "%s (WE.r) : Reply 0x%04X, hdr_len %d, tokens %d, extra_size %d, buffer_size %d\n", dev->name, cmd, hdr_len, wrqu->data.length, extra_size, buffer_size); printk(KERN_DEBUG "%s (WE.r) : Reply 0x%04X, hdr_len %d, tokens %d, extra_size %d, buffer_size %d\n", dev->name, cmd, hdr_len, wrqu->data.length, extra_size, buffer_size);
...@@ -1641,14 +1659,14 @@ static inline int rtnetlink_private_set(struct net_device * dev, ...@@ -1641,14 +1659,14 @@ static inline int rtnetlink_private_set(struct net_device * dev,
/* Does it fits in wrqu ? */ /* Does it fits in wrqu ? */
if((descr->set_args & IW_PRIV_SIZE_FIXED) && if((descr->set_args & IW_PRIV_SIZE_FIXED) &&
(extra_size <= IFNAMSIZ)) { (extra_size <= IFNAMSIZ)) {
hdr_len = IW_EV_LCP_LEN + extra_size; hdr_len = IW_EV_LCP_PK_LEN + extra_size;
extra_size = 0; extra_size = 0;
} else { } else {
hdr_len = IW_EV_POINT_LEN; hdr_len = IW_EV_POINT_PK_LEN;
} }
/* Extract fixed header from request. This is properly aligned. */ /* Extract fixed header from request. This is properly aligned. */
wrqu = &request->u; wrqu = (union iwreq_data *) (((char *) request) + IW_EV_LCP_PK_LEN);
/* Check if wrqu is complete */ /* Check if wrqu is complete */
if(request_len < hdr_len) { if(request_len < hdr_len) {
...@@ -1675,7 +1693,7 @@ static inline int rtnetlink_private_set(struct net_device * dev, ...@@ -1675,7 +1693,7 @@ static inline int rtnetlink_private_set(struct net_device * dev,
/* Put wrqu in the right place (skip pointer) */ /* Put wrqu in the right place (skip pointer) */
memcpy(((char *) &wrqu_point) + IW_EV_POINT_OFF, memcpy(((char *) &wrqu_point) + IW_EV_POINT_OFF,
wrqu, IW_EV_POINT_LEN - IW_EV_LCP_LEN); wrqu, IW_EV_POINT_PK_LEN - IW_EV_LCP_PK_LEN);
/* Does it fits within bounds ? */ /* Does it fits within bounds ? */
if(wrqu_point.data.length > (descr->set_args & if(wrqu_point.data.length > (descr->set_args &
...@@ -1738,7 +1756,7 @@ int wireless_rtnetlink_get(struct net_device * dev, ...@@ -1738,7 +1756,7 @@ int wireless_rtnetlink_get(struct net_device * dev,
iw_handler handler; iw_handler handler;
/* Check length */ /* Check length */
if(len < IW_EV_LCP_LEN) { if(len < IW_EV_LCP_PK_LEN) {
printk(KERN_DEBUG "%s (WE.r) : RtNetlink request too short (%d)\n", printk(KERN_DEBUG "%s (WE.r) : RtNetlink request too short (%d)\n",
dev->name, len); dev->name, len);
return -EINVAL; return -EINVAL;
...@@ -1822,7 +1840,7 @@ int wireless_rtnetlink_set(struct net_device * dev, ...@@ -1822,7 +1840,7 @@ int wireless_rtnetlink_set(struct net_device * dev,
iw_handler handler; iw_handler handler;
/* Check length */ /* Check length */
if(len < IW_EV_LCP_LEN) { if(len < IW_EV_LCP_PK_LEN) {
printk(KERN_DEBUG "%s (WE.r) : RtNetlink request too short (%d)\n", printk(KERN_DEBUG "%s (WE.r) : RtNetlink request too short (%d)\n",
dev->name, len); dev->name, len);
return -EINVAL; return -EINVAL;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册