/* * ioctl32.c: Conversion between 32bit and 64bit native ioctls. * * Copyright (C) 1997-2000 Jakub Jelinek (jakub@redhat.com) * Copyright (C) 1998 Eddie C. Dost (ecd@skynet.be) * Copyright (C) 2001,2002 Andi Kleen, SuSE Labs * Copyright (C) 2003 Pavel Machek (pavel@suse.cz) * * These routines maintain argument size conversion between 32bit and 64bit * ioctls. */ #include <linux/config.h>#include <linux/types.h>#include <linux/compat.h>#include <linux/kernel.h>#include <linux/capability.h>#include <linux/compiler.h>#include <linux/sched.h>#include <linux/smp.h>#include <linux/smp_lock.h>#include <linux/ioctl.h>#include <linux/if.h>#include <linux/if_bridge.h>#include <linux/slab.h>#include <linux/hdreg.h>#include <linux/raid/md.h>#include <linux/kd.h>#include <linux/dirent.h>#include <linux/route.h>#include <linux/in6.h>#include <linux/ipv6_route.h>#include <linux/skbuff.h>#include <linux/netlink.h>#include <linux/vt.h>#include <linux/fs.h>#include <linux/file.h>#include <linux/fd.h>#include <linux/ppp_defs.h>#include <linux/if_ppp.h>#include <linux/if_pppox.h>#include <linux/mtio.h>#include <linux/cdrom.h>#include <linux/loop.h>#include <linux/auto_fs.h>#include <linux/auto_fs4.h>#include <linux/devfs_fs.h>#include <linux/tty.h>#include <linux/vt_kern.h>#include <linux/fb.h>#include <linux/ext2_fs.h>#include <linux/ext3_jbd.h>#include <linux/ext3_fs.h>#include <linux/videodev.h>#include <linux/netdevice.h>#include <linux/raw.h>#include <linux/smb_fs.h>#include <linux/blkpg.h>#include <linux/blkdev.h>#include <linux/elevator.h>#include <linux/rtc.h>#include <linux/pci.h>#include <linux/module.h>#include <linux/serial.h>#include <linux/reiserfs_fs.h>#include <linux/if_tun.h>#include <linux/ctype.h>#include <linux/ioctl32.h>#include <linux/syscalls.h>#include <linux/ncp_fs.h>#include <linux/i2c.h>#include <linux/i2c-dev.h>#include <linux/wireless.h>#include <linux/atalk.h>#include <linux/blktrace_api.h> #include <net/sock.h> /* siocdevprivate_ioctl */#include <net/bluetooth/bluetooth.h>#include <net/bluetooth/hci.h>#include <net/bluetooth/rfcomm.h> #include <linux/capi.h> #include <scsi/scsi.h>#include <scsi/scsi_ioctl.h>#include <scsi/sg.h> #include <asm/uaccess.h>#include <linux/ethtool.h>#include <linux/mii.h>#include <linux/if_bonding.h>#include <linux/watchdog.h>#include <linux/dm-ioctl.h> #include <linux/soundcard.h>#include <linux/lp.h>#include <linux/ppdev.h> #include <linux/atm.h>#include <linux/atmarp.h>#include <linux/atmclip.h>#include <linux/atmdev.h>#include <linux/atmioc.h>#include <linux/atmlec.h>#include <linux/atmmpc.h>#include <linux/atmsvc.h>#include <linux/atm_tcp.h>#include <linux/sonet.h>#include <linux/atm_suni.h>#include <linux/mtd/mtd.h> #include <linux/usb.h>#include <linux/usbdevice_fs.h>#include <linux/nbd.h>#include <linux/random.h>#include <linux/filter.h>#include <linux/msdos_fs.h>#include <linux/pktcdvd.h> #include <linux/hiddev.h> #include <linux/dvb/audio.h>#include <linux/dvb/dmx.h>#include <linux/dvb/frontend.h>#include <linux/dvb/video.h>#include <linux/lp.h> /* Aiee. Someone does not find a difference between int and long */#define EXT2_IOC32_GETFLAGS _IOR('f', 1, int)#define EXT2_IOC32_SETFLAGS _IOW('f', 2, int)#define EXT3_IOC32_GETVERSION _IOR('f', 3, int)#define EXT3_IOC32_SETVERSION _IOW('f', 4, int)#define EXT3_IOC32_GETRSVSZ _IOR('f', 5, int)#define EXT3_IOC32_SETRSVSZ _IOW('f', 6, int)#define EXT3_IOC32_GROUP_EXTEND _IOW('f', 7, unsigned int)#ifdef CONFIG_JBD_DEBUG#define EXT3_IOC32_WAIT_FOR_READONLY _IOR('f', 99, int)#endif #define EXT2_IOC32_GETVERSION _IOR('v', 1, int)#define EXT2_IOC32_SETVERSION _IOW('v', 2, int) static int do_ioctl32_pointer(unsigned int fd, unsigned int cmd, unsigned long arg, struct file *f){ return sys_ioctl(fd, cmd, (unsigned long)compat_ptr(arg));} static int w_long(unsigned int fd, unsigned int cmd, unsigned long arg){ mm_segment_t old_fs = get_fs(); int err; unsigned long val; set_fs (KERNEL_DS); err = sys_ioctl(fd, cmd, (unsigned long)&val); set_fs (old_fs); if (!err && put_user(val, (u32 __user *)compat_ptr(arg))) return -EFAULT; return err;} static int rw_long(unsigned int fd, unsigned int cmd, unsigned long arg){ mm_segment_t old_fs = get_fs(); u32 __user *argptr = compat_ptr(arg); int err; unsigned long val; if(get_user(val, argptr)) return -EFAULT; set_fs (KERNEL_DS); err = sys_ioctl(fd, cmd, (unsigned long)&val); set_fs (old_fs); if (!err && put_user(val, argptr)) return -EFAULT; return err;} static int do_ext2_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg){ /* These are just misnamed, they actually get/put from/to user an int */ switch (cmd) { case EXT2_IOC32_GETFLAGS: cmd = EXT2_IOC_GETFLAGS; break; case EXT2_IOC32_SETFLAGS: cmd = EXT2_IOC_SETFLAGS; break; case EXT2_IOC32_GETVERSION: cmd = EXT2_IOC_GETVERSION; break; case EXT2_IOC32_SETVERSION: cmd = EXT2_IOC_SETVERSION; break; } return sys_ioctl(fd, cmd, (unsigned long)compat_ptr(arg));} static int do_ext3_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg){ /* These are just misnamed, they actually get/put from/to user an int */ switch (cmd) { case EXT3_IOC32_GETVERSION: cmd = EXT3_IOC_GETVERSION; break; case EXT3_IOC32_SETVERSION: cmd = EXT3_IOC_SETVERSION; break; case EXT3_IOC32_GETRSVSZ: cmd = EXT3_IOC_GETRSVSZ; break; case EXT3_IOC32_SETRSVSZ: cmd = EXT3_IOC_SETRSVSZ; break; case EXT3_IOC32_GROUP_EXTEND: cmd = EXT3_IOC_GROUP_EXTEND; break;#ifdef CONFIG_JBD_DEBUG case EXT3_IOC32_WAIT_FOR_READONLY: cmd = EXT3_IOC_WAIT_FOR_READONLY; break;#endif } return sys_ioctl(fd, cmd, (unsigned long)compat_ptr(arg));} struct compat_dmx_event { dmx_event_t event; compat_time_t timeStamp; union { dmx_scrambling_status_t scrambling; } u;}; static int do_dmx_get_event(unsigned int fd, unsigned int cmd, unsigned long arg){ struct dmx_event kevent; mm_segment_t old_fs = get_fs(); int err; set_fs(KERNEL_DS); err = sys_ioctl(fd, cmd, (unsigned long) &kevent); set_fs(old_fs); if (!err) { struct compat_dmx_event __user *up = compat_ptr(arg); err = put_user(kevent.event, &up->event); err |= put_user(kevent.timeStamp, &up->timeStamp); err |= put_user(kevent.u.scrambling, &up->u.scrambling); if (err) err = -EFAULT; } return err;} struct compat_video_event { int32_t type; compat_time_t timestamp; union { video_size_t size; unsigned int frame_rate; } u;}; static int do_video_get_event(unsigned int fd, unsigned int cmd, unsigned long arg){ struct video_event kevent; mm_segment_t old_fs = get_fs(); int err; set_fs(KERNEL_DS); err = sys_ioctl(fd, cmd, (unsigned long) &kevent); set_fs(old_fs); if (!err) { struct compat_video_event __user *up = compat_ptr(arg); err = put_user(kevent.type, &up->type); err |= put_user(kevent.timestamp, &up->timestamp); err |= put_user(kevent.u.size.w, &up->u.size.w); err |= put_user(kevent.u.size.h, &up->u.size.h); err |= put_user(kevent.u.size.aspect_ratio, &up->u.size.aspect_ratio); if (err) err = -EFAULT; } return err;} struct compat_video_still_picture { compat_uptr_t iFrame; int32_t size;}; static int do_video_stillpicture(unsigned int fd, unsigned int cmd, unsigned long arg){ struct compat_video_still_picture __user *up; struct video_still_picture __user *up_native; compat_uptr_t fp; int32_t size; int err; up = (struct compat_video_still_picture __user *) arg; err = get_user(fp, &up->iFrame); err |= get_user(size, &up->size); if (err) return -EFAULT; up_native = compat_alloc_user_space(sizeof(struct video_still_picture)); put_user(compat_ptr(fp), &up_native->iFrame); put_user(size, &up_native->size); err = sys_ioctl(fd, cmd, (unsigned long) up_native); return err;} struct compat_video_spu_palette { int length; compat_uptr_t palette;}; static int do_video_set_spu_palette(unsigned int fd, unsigned int cmd, unsigned long arg){ struct compat_video_spu_palette __user *up; struct video_spu_palette __user *up_native; compat_uptr_t palp; int length, err; up = (struct compat_video_spu_palette __user *) arg; err = get_user(palp, &up->palette); err |= get_user(length, &up->length); up_native = compat_alloc_user_space(sizeof(struct video_spu_palette)); put_user(compat_ptr(palp), &up_native->palette); put_user(length, &up_native->length); err = sys_ioctl(fd, cmd, (unsigned long) up_native); return err;} #ifdef CONFIG_NETstatic int do_siocgstamp(unsigned int fd, unsigned int cmd, unsigned long arg){ struct compat_timeval __user *up = compat_ptr(arg); struct timeval ktv; mm_segment_t old_fs = get_fs(); int err; set_fs(KERNEL_DS); err = sys_ioctl(fd, cmd, (unsigned long)&ktv); set_fs(old_fs); if(!err) { err = put_user(ktv.tv_sec, &up->tv_sec); err |= __put_user(ktv.tv_usec, &up->tv_usec); } return err;} struct ifmap32 { compat_ulong_t mem_start; compat_ulong_t mem_end; unsigned short base_addr; unsigned char irq; unsigned char dma; unsigned char port;}; struct ifreq32 {#define IFHWADDRLEN 6#define IFNAMSIZ 16 union { char ifrn_name[IFNAMSIZ]; /* if name, e.g. "en0" */ } ifr_ifrn; union { struct sockaddr ifru_addr; struct sockaddr ifru_dstaddr; struct sockaddr ifru_broadaddr; struct sockaddr ifru_netmask; struct sockaddr ifru_hwaddr; short ifru_flags; compat_int_t ifru_ivalue; compat_int_t ifru_mtu; struct ifmap32 ifru_map; char ifru_slave[IFNAMSIZ]; /* Just fits the size */ char ifru_newname[IFNAMSIZ]; compat_caddr_t ifru_data; /* XXXX? ifru_settings should be here */ } ifr_ifru;}; struct ifconf32 { compat_int_t ifc_len; /* size of buffer */ compat_caddr_t ifcbuf;}; static int dev_ifname32(unsigned int fd, unsigned int cmd, unsigned long arg){ struct net_device *dev; struct ifreq32 ifr32; int err; if (copy_from_user(&ifr32, compat_ptr(arg), sizeof(ifr32))) return -EFAULT; dev = dev_get_by_index(ifr32.ifr_ifindex); if (!dev) return -ENODEV; strlcpy(ifr32.ifr_name, dev->name, sizeof(ifr32.ifr_name)); dev_put(dev); err = copy_to_user(compat_ptr(arg), &ifr32, sizeof(ifr32)); return (err ? -EFAULT : 0);} static int dev_ifconf(unsigned int fd, unsigned int cmd, unsigned long arg){ struct ifconf32 ifc32; struct ifconf ifc; struct ifconf __user *uifc; struct ifreq32 __user *ifr32; struct ifreq __user *ifr; unsigned int i, j; int err; if (copy_from_user(&ifc32, compat_ptr(arg), sizeof(struct ifconf32))) return -EFAULT; if (ifc32.ifcbuf == 0) { ifc32.ifc_len = 0; ifc.ifc_len = 0; ifc.ifc_req = NULL; uifc = compat_alloc_user_space(sizeof(struct ifconf)); } else { size_t len =((ifc32.ifc_len / sizeof (struct ifreq32)) + 1) * sizeof (struct ifreq); uifc = compat_alloc_user_space(sizeof(struct ifconf) + len); ifc.ifc_len = len; ifr = ifc.ifc_req = (void __user *)(uifc + 1); ifr32 = compat_ptr(ifc32.ifcbuf); for (i = 0; i < ifc32.ifc_len; i += sizeof (struct ifreq32)) { if (copy_in_user(ifr, ifr32, sizeof(struct ifreq32))) return -EFAULT; ifr++; ifr32++; } } if (copy_to_user(uifc, &ifc, sizeof(struct ifconf))) return -EFAULT; err = sys_ioctl (fd, SIOCGIFCONF, (unsigned long)uifc); if (err) return err; if (copy_from_user(&ifc, uifc, sizeof(struct ifconf))) return -EFAULT; ifr = ifc.ifc_req; ifr32 = compat_ptr(ifc32.ifcbuf); for (i = 0, j = 0; i + sizeof (struct ifreq32) <= ifc32.ifc_len && j < ifc.ifc_len; i += sizeof (struct ifreq32), j += sizeof (struct ifreq)) { if (copy_in_user(ifr32, ifr, sizeof (struct ifreq32))) return -EFAULT; ifr32++; ifr++; } if (ifc32.ifcbuf == 0) { /* Translate from 64-bit structure multiple to * a 32-bit one. */ i = ifc.ifc_len; i = ((i / sizeof(struct ifreq)) * sizeof(struct ifreq32)); ifc32.ifc_len = i; } else { ifc32.ifc_len = i; } if (copy_to_user(compat_ptr(arg), &ifc32, sizeof(struct ifconf32))) return -EFAULT; return 0;} static int ethtool_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg){ struct ifreq __user *ifr; struct ifreq32 __user *ifr32; u32 data; void __user *datap; ifr = compat_alloc_user_space(sizeof(*ifr)); ifr32 = compat_ptr(arg); if (copy_in_user(&ifr->ifr_name, &ifr32->ifr_name, IFNAMSIZ)) return -EFAULT; if (get_user(data, &ifr32->ifr_ifru.ifru_data)) return -EFAULT; datap = compat_ptr(data); if (put_user(datap, &ifr->ifr_ifru.ifru_data)) return -EFAULT; return sys_ioctl(fd, cmd, (unsigned long) ifr);} static int bond_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg){ struct ifreq kifr; struct ifreq __user *uifr;Lines 1–500 of 2987. Load more
/* * ioctl32.c: Conversion between 32bit and 64bit native ioctls. * * Copyright (C) 1997-2000 Jakub Jelinek (jakub@redhat.com) * Copyright (C) 1998 Eddie C. Dost (ecd@skynet.be) * Copyright (C) 2001,2002 Andi Kleen, SuSE Labs * Copyright (C) 2003 Pavel Machek (pavel@suse.cz) * * These routines maintain argument size conversion between 32bit and 64bit * ioctls. */ #include <linux/config.h> #include <linux/types.h> #include <linux/compat.h> #include <linux/kernel.h> #include <linux/capability.h> #include <linux/compiler.h> #include <linux/sched.h> #include <linux/smp.h> #include <linux/smp_lock.h> #include <linux/ioctl.h> #include <linux/if.h> #include <linux/if_bridge.h> #include <linux/slab.h> #include <linux/hdreg.h> #include <linux/raid/md.h> #include <linux/kd.h> #include <linux/dirent.h> #include <linux/route.h> #include <linux/in6.h> #include <linux/ipv6_route.h> #include <linux/skbuff.h> #include <linux/netlink.h> #include <linux/vt.h> #include <linux/fs.h> #include <linux/file.h> #include <linux/fd.h> #include <linux/ppp_defs.h> #include <linux/if_ppp.h> #include <linux/if_pppox.h> #include <linux/mtio.h> #include <linux/cdrom.h> #include <linux/loop.h> #include <linux/auto_fs.h> #include <linux/auto_fs4.h> #include <linux/devfs_fs.h> #include <linux/tty.h> #include <linux/vt_kern.h> #include <linux/fb.h> #include <linux/ext2_fs.h> #include <linux/ext3_jbd.h> #include <linux/ext3_fs.h> #include <linux/videodev.h> #include <linux/netdevice.h> #include <linux/raw.h> #include <linux/smb_fs.h> #include <linux/blkpg.h> #include <linux/blkdev.h> #include <linux/elevator.h> #include <linux/rtc.h> #include <linux/pci.h> #include <linux/module.h> #include <linux/serial.h> #include <linux/reiserfs_fs.h> #include <linux/if_tun.h> #include <linux/ctype.h> #include <linux/ioctl32.h> #include <linux/syscalls.h> #include <linux/ncp_fs.h> #include <linux/i2c.h> #include <linux/i2c-dev.h> #include <linux/wireless.h> #include <linux/atalk.h> #include <linux/blktrace_api.h> #include <net/sock.h> /* siocdevprivate_ioctl */ #include <net/bluetooth/bluetooth.h> #include <net/bluetooth/hci.h> #include <net/bluetooth/rfcomm.h> #include <linux/capi.h> #include <scsi/scsi.h> #include <scsi/scsi_ioctl.h> #include <scsi/sg.h> #include <asm/uaccess.h> #include <linux/ethtool.h> #include <linux/mii.h> #include <linux/if_bonding.h> #include <linux/watchdog.h> #include <linux/dm-ioctl.h> #include <linux/soundcard.h> #include <linux/lp.h> #include <linux/ppdev.h> #include <linux/atm.h> #include <linux/atmarp.h> #include <linux/atmclip.h> #include <linux/atmdev.h> #include <linux/atmioc.h> #include <linux/atmlec.h> #include <linux/atmmpc.h> #include <linux/atmsvc.h> #include <linux/atm_tcp.h> #include <linux/sonet.h> #include <linux/atm_suni.h> #include <linux/mtd/mtd.h> #include <linux/usb.h> #include <linux/usbdevice_fs.h> #include <linux/nbd.h> #include <linux/random.h> #include <linux/filter.h> #include <linux/msdos_fs.h> #include <linux/pktcdvd.h> #include <linux/hiddev.h> #include <linux/dvb/audio.h> #include <linux/dvb/dmx.h> #include <linux/dvb/frontend.h> #include <linux/dvb/video.h> #include <linux/lp.h> /* Aiee. Someone does not find a difference between int and long */ #define EXT2_IOC32_GETFLAGS _IOR('f', 1, int) #define EXT2_IOC32_SETFLAGS _IOW('f', 2, int) #define EXT3_IOC32_GETVERSION _IOR('f', 3, int) #define EXT3_IOC32_SETVERSION _IOW('f', 4, int) #define EXT3_IOC32_GETRSVSZ _IOR('f', 5, int) #define EXT3_IOC32_SETRSVSZ _IOW('f', 6, int) #define EXT3_IOC32_GROUP_EXTEND _IOW('f', 7, unsigned int) #ifdef CONFIG_JBD_DEBUG #define EXT3_IOC32_WAIT_FOR_READONLY _IOR('f', 99, int) #endif #define EXT2_IOC32_GETVERSION _IOR('v', 1, int) #define EXT2_IOC32_SETVERSION _IOW('v', 2, int) static int do_ioctl32_pointer(unsigned int fd, unsigned int cmd, unsigned long arg, struct file *f) { return sys_ioctl(fd, cmd, (unsigned long)compat_ptr(arg)); } static int w_long(unsigned int fd, unsigned int cmd, unsigned long arg) { mm_segment_t old_fs = get_fs(); int err; unsigned long val; set_fs (KERNEL_DS); err = sys_ioctl(fd, cmd, (unsigned long)&val); set_fs (old_fs); if (!err && put_user(val, (u32 __user *)compat_ptr(arg))) return -EFAULT; return err; } static int rw_long(unsigned int fd, unsigned int cmd, unsigned long arg) { mm_segment_t old_fs = get_fs(); u32 __user *argptr = compat_ptr(arg); int err; unsigned long val; if(get_user(val, argptr)) return -EFAULT; set_fs (KERNEL_DS); err = sys_ioctl(fd, cmd, (unsigned long)&val); set_fs (old_fs); if (!err && put_user(val, argptr)) return -EFAULT; return err; } static int do_ext2_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg) { /* These are just misnamed, they actually get/put from/to user an int */ switch (cmd) { case EXT2_IOC32_GETFLAGS: cmd = EXT2_IOC_GETFLAGS; break; case EXT2_IOC32_SETFLAGS: cmd = EXT2_IOC_SETFLAGS; break; case EXT2_IOC32_GETVERSION: cmd = EXT2_IOC_GETVERSION; break; case EXT2_IOC32_SETVERSION: cmd = EXT2_IOC_SETVERSION; break; } return sys_ioctl(fd, cmd, (unsigned long)compat_ptr(arg)); } static int do_ext3_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg) { /* These are just misnamed, they actually get/put from/to user an int */ switch (cmd) { case EXT3_IOC32_GETVERSION: cmd = EXT3_IOC_GETVERSION; break; case EXT3_IOC32_SETVERSION: cmd = EXT3_IOC_SETVERSION; break; case EXT3_IOC32_GETRSVSZ: cmd = EXT3_IOC_GETRSVSZ; break; case EXT3_IOC32_SETRSVSZ: cmd = EXT3_IOC_SETRSVSZ; break; case EXT3_IOC32_GROUP_EXTEND: cmd = EXT3_IOC_GROUP_EXTEND; break; #ifdef CONFIG_JBD_DEBUG case EXT3_IOC32_WAIT_FOR_READONLY: cmd = EXT3_IOC_WAIT_FOR_READONLY; break; #endif } return sys_ioctl(fd, cmd, (unsigned long)compat_ptr(arg)); } struct compat_dmx_event { dmx_event_t event; compat_time_t timeStamp; union { dmx_scrambling_status_t scrambling; } u; }; static int do_dmx_get_event(unsigned int fd, unsigned int cmd, unsigned long arg) { struct dmx_event kevent; mm_segment_t old_fs = get_fs(); int err; set_fs(KERNEL_DS); err = sys_ioctl(fd, cmd, (unsigned long) &kevent); set_fs(old_fs); if (!err) { struct compat_dmx_event __user *up = compat_ptr(arg); err = put_user(kevent.event, &up->event); err |= put_user(kevent.timeStamp, &up->timeStamp); err |= put_user(kevent.u.scrambling, &up->u.scrambling); if (err) err = -EFAULT; } return err; } struct compat_video_event { int32_t type; compat_time_t timestamp; union { video_size_t size; unsigned int frame_rate; } u; }; static int do_video_get_event(unsigned int fd, unsigned int cmd, unsigned long arg) { struct video_event kevent; mm_segment_t old_fs = get_fs(); int err; set_fs(KERNEL_DS); err = sys_ioctl(fd, cmd, (unsigned long) &kevent); set_fs(old_fs); if (!err) { struct compat_video_event __user *up = compat_ptr(arg); err = put_user(kevent.type, &up->type); err |= put_user(kevent.timestamp, &up->timestamp); err |= put_user(kevent.u.size.w, &up->u.size.w); err |= put_user(kevent.u.size.h, &up->u.size.h); err |= put_user(kevent.u.size.aspect_ratio, &up->u.size.aspect_ratio); if (err) err = -EFAULT; } return err; } struct compat_video_still_picture { compat_uptr_t iFrame; int32_t size; }; static int do_video_stillpicture(unsigned int fd, unsigned int cmd, unsigned long arg) { struct compat_video_still_picture __user *up; struct video_still_picture __user *up_native; compat_uptr_t fp; int32_t size; int err; up = (struct compat_video_still_picture __user *) arg; err = get_user(fp, &up->iFrame); err |= get_user(size, &up->size); if (err) return -EFAULT; up_native = compat_alloc_user_space(sizeof(struct video_still_picture)); put_user(compat_ptr(fp), &up_native->iFrame); put_user(size, &up_native->size); err = sys_ioctl(fd, cmd, (unsigned long) up_native); return err; } struct compat_video_spu_palette { int length; compat_uptr_t palette; }; static int do_video_set_spu_palette(unsigned int fd, unsigned int cmd, unsigned long arg) { struct compat_video_spu_palette __user *up; struct video_spu_palette __user *up_native; compat_uptr_t palp; int length, err; up = (struct compat_video_spu_palette __user *) arg; err = get_user(palp, &up->palette); err |= get_user(length, &up->length); up_native = compat_alloc_user_space(sizeof(struct video_spu_palette)); put_user(compat_ptr(palp), &up_native->palette); put_user(length, &up_native->length); err = sys_ioctl(fd, cmd, (unsigned long) up_native); return err; } #ifdef CONFIG_NET static int do_siocgstamp(unsigned int fd, unsigned int cmd, unsigned long arg) { struct compat_timeval __user *up = compat_ptr(arg); struct timeval ktv; mm_segment_t old_fs = get_fs(); int err; set_fs(KERNEL_DS); err = sys_ioctl(fd, cmd, (unsigned long)&ktv); set_fs(old_fs); if(!err) { err = put_user(ktv.tv_sec, &up->tv_sec); err |= __put_user(ktv.tv_usec, &up->tv_usec); } return err; } struct ifmap32 { compat_ulong_t mem_start; compat_ulong_t mem_end; unsigned short base_addr; unsigned char irq; unsigned char dma; unsigned char port; }; struct ifreq32 { #define IFHWADDRLEN 6 #define IFNAMSIZ 16 union { char ifrn_name[IFNAMSIZ]; /* if name, e.g. "en0" */ } ifr_ifrn; union { struct sockaddr ifru_addr; struct sockaddr ifru_dstaddr; struct sockaddr ifru_broadaddr; struct sockaddr ifru_netmask; struct sockaddr ifru_hwaddr; short ifru_flags; compat_int_t ifru_ivalue; compat_int_t ifru_mtu; struct ifmap32 ifru_map; char ifru_slave[IFNAMSIZ]; /* Just fits the size */ char ifru_newname[IFNAMSIZ]; compat_caddr_t ifru_data; /* XXXX? ifru_settings should be here */ } ifr_ifru; }; struct ifconf32 { compat_int_t ifc_len; /* size of buffer */ compat_caddr_t ifcbuf; }; static int dev_ifname32(unsigned int fd, unsigned int cmd, unsigned long arg) { struct net_device *dev; struct ifreq32 ifr32; int err; if (copy_from_user(&ifr32, compat_ptr(arg), sizeof(ifr32))) return -EFAULT; dev = dev_get_by_index(ifr32.ifr_ifindex); if (!dev) return -ENODEV; strlcpy(ifr32.ifr_name, dev->name, sizeof(ifr32.ifr_name)); dev_put(dev); err = copy_to_user(compat_ptr(arg), &ifr32, sizeof(ifr32)); return (err ? -EFAULT : 0); } static int dev_ifconf(unsigned int fd, unsigned int cmd, unsigned long arg) { struct ifconf32 ifc32; struct ifconf ifc; struct ifconf __user *uifc; struct ifreq32 __user *ifr32; struct ifreq __user *ifr; unsigned int i, j; int err; if (copy_from_user(&ifc32, compat_ptr(arg), sizeof(struct ifconf32))) return -EFAULT; if (ifc32.ifcbuf == 0) { ifc32.ifc_len = 0; ifc.ifc_len = 0; ifc.ifc_req = NULL; uifc = compat_alloc_user_space(sizeof(struct ifconf)); } else { size_t len =((ifc32.ifc_len / sizeof (struct ifreq32)) + 1) * sizeof (struct ifreq); uifc = compat_alloc_user_space(sizeof(struct ifconf) + len); ifc.ifc_len = len; ifr = ifc.ifc_req = (void __user *)(uifc + 1); ifr32 = compat_ptr(ifc32.ifcbuf); for (i = 0; i < ifc32.ifc_len; i += sizeof (struct ifreq32)) { if (copy_in_user(ifr, ifr32, sizeof(struct ifreq32))) return -EFAULT; ifr++; ifr32++; } } if (copy_to_user(uifc, &ifc, sizeof(struct ifconf))) return -EFAULT; err = sys_ioctl (fd, SIOCGIFCONF, (unsigned long)uifc); if (err) return err; if (copy_from_user(&ifc, uifc, sizeof(struct ifconf))) return -EFAULT; ifr = ifc.ifc_req; ifr32 = compat_ptr(ifc32.ifcbuf); for (i = 0, j = 0; i + sizeof (struct ifreq32) <= ifc32.ifc_len && j < ifc.ifc_len; i += sizeof (struct ifreq32), j += sizeof (struct ifreq)) { if (copy_in_user(ifr32, ifr, sizeof (struct ifreq32))) return -EFAULT; ifr32++; ifr++; } if (ifc32.ifcbuf == 0) { /* Translate from 64-bit structure multiple to * a 32-bit one. */ i = ifc.ifc_len; i = ((i / sizeof(struct ifreq)) * sizeof(struct ifreq32)); ifc32.ifc_len = i; } else { ifc32.ifc_len = i; } if (copy_to_user(compat_ptr(arg), &ifc32, sizeof(struct ifconf32))) return -EFAULT; return 0; } static int ethtool_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg) { struct ifreq __user *ifr; struct ifreq32 __user *ifr32; u32 data; void __user *datap; ifr = compat_alloc_user_space(sizeof(*ifr)); ifr32 = compat_ptr(arg); if (copy_in_user(&ifr->ifr_name, &ifr32->ifr_name, IFNAMSIZ)) return -EFAULT; if (get_user(data, &ifr32->ifr_ifru.ifru_data)) return -EFAULT; datap = compat_ptr(data); if (put_user(datap, &ifr->ifr_ifru.ifru_data)) return -EFAULT; return sys_ioctl(fd, cmd, (unsigned long) ifr); } static int bond_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg) { struct ifreq kifr; struct ifreq __user *uifr;