mirror of
https://github.com/FEX-Emu/linux.git
synced 2024-12-15 05:11:32 +00:00
[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: Jean Tourrilhes <jt@hpl.hp.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
This commit is contained in:
parent
ed4bb10631
commit
c2805fbb86
@ -1,10 +1,10 @@
|
|||||||
/*
|
/*
|
||||||
* 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 @@
|
|||||||
* (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 @@
|
|||||||
* - 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
|
|||||||
#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 */
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
/*
|
/*
|
||||||
* 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 @@
|
|||||||
* 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 @@
|
|||||||
* - 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 */
|
|||||||
/* 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 */
|
|||||||
/* 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 */
|
|||||||
/* 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 */
|
|||||||
/* 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)
|
|||||||
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 @@
|
|||||||
* 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 @@
|
|||||||
* 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[] = {
|
|||||||
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,
|
|||||||
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,
|
|||||||
|
|
||||||
/* 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,
|
|||||||
(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,
|
|||||||
|
|
||||||
/* 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,
|
|||||||
/* 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,
|
|||||||
#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,
|
|||||||
|
|
||||||
/* 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,
|
|||||||
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,
|
|||||||
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,
|
|||||||
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,
|
|||||||
|
|
||||||
/* 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,
|
|||||||
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,
|
|||||||
/* 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,
|
|||||||
|
|
||||||
/* 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,
|
|||||||
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,
|
|||||||
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;
|
||||||
|
Loading…
Reference in New Issue
Block a user