diff options
author | 2007-09-14 14:35:38 -0400 | |
---|---|---|
committer | 2007-09-14 14:35:38 -0400 | |
commit | 53c5725581cce8a29925afd4eae71fa8c7ce551f (patch) | |
tree | e4e966b5e9dc225f740ae183951b226e8a3dbf42 /fs/compat_ioctl.c | |
parent | [PATCH] bcm43xx: Fix cancellation of work queue crashes (diff) | |
download | linux-53c5725581cce8a29925afd4eae71fa8c7ce551f.tar.gz linux-53c5725581cce8a29925afd4eae71fa8c7ce551f.tar.bz2 linux-53c5725581cce8a29925afd4eae71fa8c7ce551f.zip |
As struct iw_point is bi-directional payload, we should copy back the content
on return from ioctl calls
Signed-off-by: Masakazu Mokuno <mokuno@sm.sony.co.jp>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'fs/compat_ioctl.c')
-rw-r--r-- | fs/compat_ioctl.c | 22 |
1 files changed, 18 insertions, 4 deletions
diff --git a/fs/compat_ioctl.c b/fs/compat_ioctl.c index a6c9078af124..5a5b7116cefb 100644 --- a/fs/compat_ioctl.c +++ b/fs/compat_ioctl.c @@ -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 |