Commit 98978edb authored by John W. Linville's avatar John W. Linville

[PATCH] wireless: WE-20 compatibility for ESSID and NICKN ioctls

WE-21 changed the ABI for the SIOC[SG]IW{ESSID,NICKN} ioctls by dropping
NULL termination.  This patch adds compatibility code so that WE-21 can
work properly with WE-20 (and older) tools.
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent 51018b0a
...@@ -748,11 +748,39 @@ static int ioctl_standard_call(struct net_device * dev, ...@@ -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, ...@@ -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, ...@@ -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 */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment