|
@@ -748,11 +748,39 @@ static int ioctl_standard_call(struct net_device * dev,
|
|
int extra_size;
|
|
int extra_size;
|
|
int user_length = 0;
|
|
int user_length = 0;
|
|
int err;
|
|
int err;
|
|
|
|
+ int essid_compat = 0;
|
|
|
|
|
|
/* 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... */
|
|
extra_size = descr->max_tokens * descr->token_size;
|
|
extra_size = descr->max_tokens * descr->token_size;
|
|
|
|
|
|
|
|
+ /* Check need for ESSID compatibility for WE < 21 */
|
|
|
|
+ switch (cmd) {
|
|
|
|
+ case SIOCSIWESSID:
|
|
|
|
+ case SIOCGIWESSID:
|
|
|
|
+ case SIOCSIWNICKN:
|
|
|
|
+ case SIOCGIWNICKN:
|
|
|
|
+ if (iwr->u.data.length == descr->max_tokens + 1)
|
|
|
|
+ essid_compat = 1;
|
|
|
|
+ else if (IW_IS_SET(cmd) && (iwr->u.data.length != 0)) {
|
|
|
|
+ char essid[IW_ESSID_MAX_SIZE + 1];
|
|
|
|
+
|
|
|
|
+ err = copy_from_user(essid, iwr->u.data.pointer,
|
|
|
|
+ iwr->u.data.length *
|
|
|
|
+ descr->token_size);
|
|
|
|
+ if (err)
|
|
|
|
+ return -EFAULT;
|
|
|
|
+
|
|
|
|
+ if (essid[iwr->u.data.length - 1] == '\0')
|
|
|
|
+ essid_compat = 1;
|
|
|
|
+ }
|
|
|
|
+ break;
|
|
|
|
+ default:
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ iwr->u.data.length -= essid_compat;
|
|
|
|
+
|
|
/* Check what user space is giving us */
|
|
/* Check what user space is giving us */
|
|
if(IW_IS_SET(cmd)) {
|
|
if(IW_IS_SET(cmd)) {
|
|
/* Check NULL pointer */
|
|
/* Check NULL pointer */
|
|
@@ -795,7 +823,8 @@ static int ioctl_standard_call(struct net_device * dev,
|
|
#endif /* WE_IOCTL_DEBUG */
|
|
#endif /* WE_IOCTL_DEBUG */
|
|
|
|
|
|
/* Create the kernel buffer */
|
|
/* Create the kernel buffer */
|
|
- extra = kmalloc(extra_size, GFP_KERNEL);
|
|
|
|
|
|
+ /* kzalloc ensures NULL-termination for essid_compat */
|
|
|
|
+ extra = kzalloc(extra_size, GFP_KERNEL);
|
|
if (extra == NULL) {
|
|
if (extra == NULL) {
|
|
return -ENOMEM;
|
|
return -ENOMEM;
|
|
}
|
|
}
|
|
@@ -819,6 +848,8 @@ static int ioctl_standard_call(struct net_device * dev,
|
|
/* Call the handler */
|
|
/* Call the handler */
|
|
ret = handler(dev, &info, &(iwr->u), extra);
|
|
ret = handler(dev, &info, &(iwr->u), extra);
|
|
|
|
|
|
|
|
+ iwr->u.data.length += essid_compat;
|
|
|
|
+
|
|
/* If we have something to return to the user */
|
|
/* If we have something to return to the user */
|
|
if (!ret && IW_IS_GET(cmd)) {
|
|
if (!ret && IW_IS_GET(cmd)) {
|
|
/* Check if there is enough buffer up there */
|
|
/* Check if there is enough buffer up there */
|