As struct iw_point is bi-directional payload, we should copy back the content
authorMasakazu Mokuno <mokuno@sm.sony.co.jp>
Fri, 14 Sep 2007 18:35:38 +0000 (14:35 -0400)
committerJohn W. Linville <linville@tuxdriver.com>
Fri, 14 Sep 2007 18:35:38 +0000 (14:35 -0400)
on return from ioctl calls

Signed-off-by: Masakazu Mokuno <mokuno@sm.sony.co.jp>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
fs/compat_ioctl.c

index a6c9078af124b1af134c1adb6d0d229ae55e9c12..5a5b7116cefb28cc5b56a85f089985796c7b6423 100644 (file)
@@ -2311,8 +2311,10 @@ static int do_wireless_ioctl(unsigned int fd, unsigned int cmd, unsigned long ar
        struct iwreq __user *iwr_u;
        struct iw_point __user *iwp;
        struct compat_iw_point __user *iwp_u;
-       compat_caddr_t pointer;
+       compat_caddr_t pointer_u;
+       void __user *pointer;
        __u16 length, flags;
+       int ret;
 
        iwr_u = compat_ptr(arg);
        iwp_u = (struct compat_iw_point __user *) &iwr_u->u.data;
@@ -2330,17 +2332,29 @@ static int do_wireless_ioctl(unsigned int fd, unsigned int cmd, unsigned long ar
                           sizeof(iwr->ifr_ifrn.ifrn_name)))
                return -EFAULT;
 
-       if (__get_user(pointer, &iwp_u->pointer) ||
+       if (__get_user(pointer_u, &iwp_u->pointer) ||
            __get_user(length, &iwp_u->length) ||
            __get_user(flags, &iwp_u->flags))
                return -EFAULT;
 
-       if (__put_user(compat_ptr(pointer), &iwp->pointer) ||
+       if (__put_user(compat_ptr(pointer_u), &iwp->pointer) ||
            __put_user(length, &iwp->length) ||
            __put_user(flags, &iwp->flags))
                return -EFAULT;
 
-       return sys_ioctl(fd, cmd, (unsigned long) iwr);
+       ret = sys_ioctl(fd, cmd, (unsigned long) iwr);
+
+       if (__get_user(pointer, &iwp->pointer) ||
+           __get_user(length, &iwp->length) ||
+           __get_user(flags, &iwp->flags))
+               return -EFAULT;
+
+       if (__put_user(ptr_to_compat(pointer), &iwp_u->pointer) ||
+           __put_user(length, &iwp_u->length) ||
+           __put_user(flags, &iwp_u->flags))
+               return -EFAULT;
+
+       return ret;
 }
 
 /* Since old style bridge ioctl's endup using SIOCDEVPRIVATE