X-Git-Url: http://ftp.safe.ca/?a=blobdiff_plain;f=fs%2Fcompat_ioctl.c;h=7895bdb0c30444f935391b13eeb3300a1963c508;hb=789f0f89118a80a3ff5309371e5820f623ed2a53;hp=626c7483b4de4e4f076bd4ab07af690007f9a0ae;hpb=3e63cbb1efca7dd3137de1bb475e2e068e38ef23;p=safe%2Fjmp%2Flinux-2.6 diff --git a/fs/compat_ioctl.c b/fs/compat_ioctl.c index 626c748..7895bdb 100644 --- a/fs/compat_ioctl.c +++ b/fs/compat_ioctl.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include @@ -114,12 +115,6 @@ #include #endif -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(); @@ -245,428 +240,6 @@ static int do_video_set_spu_palette(unsigned int fd, unsigned int cmd, unsigned 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; -} - -static int do_siocgstampns(unsigned int fd, unsigned int cmd, unsigned long arg) -{ - struct compat_timespec __user *up = compat_ptr(arg); - struct timespec kts; - mm_segment_t old_fs = get_fs(); - int err; - - set_fs(KERNEL_DS); - err = sys_ioctl(fd, cmd, (unsigned long)&kts); - set_fs(old_fs); - if (!err) { - err = put_user(kts.tv_sec, &up->tv_sec); - err |= __put_user(kts.tv_nsec, &up->tv_nsec); - } - 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 ifreq __user *uifr; - int err; - - uifr = compat_alloc_user_space(sizeof(struct ifreq)); - if (copy_in_user(uifr, compat_ptr(arg), sizeof(struct ifreq32))) - return -EFAULT; - - err = sys_ioctl(fd, SIOCGIFNAME, (unsigned long)uifr); - if (err) - return err; - - if (copy_in_user(compat_ptr(arg), uifr, sizeof(struct ifreq32))) - return -EFAULT; - - return 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; - struct ifreq32 __user *ifr32 = compat_ptr(arg); - mm_segment_t old_fs; - int err; - u32 data; - void __user *datap; - - switch (cmd) { - case SIOCBONDENSLAVE: - case SIOCBONDRELEASE: - case SIOCBONDSETHWADDR: - case SIOCBONDCHANGEACTIVE: - if (copy_from_user(&kifr, ifr32, sizeof(struct ifreq32))) - return -EFAULT; - - old_fs = get_fs(); - set_fs (KERNEL_DS); - err = sys_ioctl (fd, cmd, (unsigned long)&kifr); - set_fs (old_fs); - - return err; - case SIOCBONDSLAVEINFOQUERY: - case SIOCBONDINFOQUERY: - uifr = compat_alloc_user_space(sizeof(*uifr)); - if (copy_in_user(&uifr->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, &uifr->ifr_ifru.ifru_data)) - return -EFAULT; - - return sys_ioctl (fd, cmd, (unsigned long)uifr); - default: - return -EINVAL; - }; -} - -static int siocdevprivate_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg) -{ - struct ifreq __user *u_ifreq64; - struct ifreq32 __user *u_ifreq32 = compat_ptr(arg); - char tmp_buf[IFNAMSIZ]; - void __user *data64; - u32 data32; - - if (copy_from_user(&tmp_buf[0], &(u_ifreq32->ifr_ifrn.ifrn_name[0]), - IFNAMSIZ)) - return -EFAULT; - if (__get_user(data32, &u_ifreq32->ifr_ifru.ifru_data)) - return -EFAULT; - data64 = compat_ptr(data32); - - u_ifreq64 = compat_alloc_user_space(sizeof(*u_ifreq64)); - - /* Don't check these user accesses, just let that get trapped - * in the ioctl handler instead. - */ - if (copy_to_user(&u_ifreq64->ifr_ifrn.ifrn_name[0], &tmp_buf[0], - IFNAMSIZ)) - return -EFAULT; - if (__put_user(data64, &u_ifreq64->ifr_ifru.ifru_data)) - return -EFAULT; - - return sys_ioctl(fd, cmd, (unsigned long) u_ifreq64); -} - -static int dev_ifsioc(unsigned int fd, unsigned int cmd, unsigned long arg) -{ - struct ifreq ifr; - struct ifreq32 __user *uifr32; - struct ifmap32 __user *uifmap32; - mm_segment_t old_fs; - int err; - - uifr32 = compat_ptr(arg); - uifmap32 = &uifr32->ifr_ifru.ifru_map; - switch (cmd) { - case SIOCSIFMAP: - err = copy_from_user(&ifr, uifr32, sizeof(ifr.ifr_name)); - err |= __get_user(ifr.ifr_map.mem_start, &uifmap32->mem_start); - err |= __get_user(ifr.ifr_map.mem_end, &uifmap32->mem_end); - err |= __get_user(ifr.ifr_map.base_addr, &uifmap32->base_addr); - err |= __get_user(ifr.ifr_map.irq, &uifmap32->irq); - err |= __get_user(ifr.ifr_map.dma, &uifmap32->dma); - err |= __get_user(ifr.ifr_map.port, &uifmap32->port); - if (err) - return -EFAULT; - break; - case SIOCSHWTSTAMP: - if (copy_from_user(&ifr, uifr32, sizeof(*uifr32))) - return -EFAULT; - ifr.ifr_data = compat_ptr(uifr32->ifr_ifru.ifru_data); - break; - default: - if (copy_from_user(&ifr, uifr32, sizeof(*uifr32))) - return -EFAULT; - break; - } - old_fs = get_fs(); - set_fs (KERNEL_DS); - err = sys_ioctl (fd, cmd, (unsigned long)&ifr); - set_fs (old_fs); - if (!err) { - switch (cmd) { - /* TUNSETIFF is defined as _IOW, it should be _IORW - * as the data is copied back to user space, but that - * cannot be fixed without breaking all existing apps. - */ - case TUNSETIFF: - case TUNGETIFF: - case SIOCGIFFLAGS: - case SIOCGIFMETRIC: - case SIOCGIFMTU: - case SIOCGIFMEM: - case SIOCGIFHWADDR: - case SIOCGIFINDEX: - case SIOCGIFADDR: - case SIOCGIFBRDADDR: - case SIOCGIFDSTADDR: - case SIOCGIFNETMASK: - case SIOCGIFTXQLEN: - if (copy_to_user(uifr32, &ifr, sizeof(*uifr32))) - return -EFAULT; - break; - case SIOCGIFMAP: - err = copy_to_user(uifr32, &ifr, sizeof(ifr.ifr_name)); - err |= __put_user(ifr.ifr_map.mem_start, &uifmap32->mem_start); - err |= __put_user(ifr.ifr_map.mem_end, &uifmap32->mem_end); - err |= __put_user(ifr.ifr_map.base_addr, &uifmap32->base_addr); - err |= __put_user(ifr.ifr_map.irq, &uifmap32->irq); - err |= __put_user(ifr.ifr_map.dma, &uifmap32->dma); - err |= __put_user(ifr.ifr_map.port, &uifmap32->port); - if (err) - err = -EFAULT; - break; - } - } - return err; -} - -struct rtentry32 { - u32 rt_pad1; - struct sockaddr rt_dst; /* target address */ - struct sockaddr rt_gateway; /* gateway addr (RTF_GATEWAY) */ - struct sockaddr rt_genmask; /* target network mask (IP) */ - unsigned short rt_flags; - short rt_pad2; - u32 rt_pad3; - unsigned char rt_tos; - unsigned char rt_class; - short rt_pad4; - short rt_metric; /* +1 for binary compatibility! */ - /* char * */ u32 rt_dev; /* forcing the device at add */ - u32 rt_mtu; /* per route MTU/Window */ - u32 rt_window; /* Window clamping */ - unsigned short rt_irtt; /* Initial RTT */ - -}; - -struct in6_rtmsg32 { - struct in6_addr rtmsg_dst; - struct in6_addr rtmsg_src; - struct in6_addr rtmsg_gateway; - u32 rtmsg_type; - u16 rtmsg_dst_len; - u16 rtmsg_src_len; - u32 rtmsg_metric; - u32 rtmsg_info; - u32 rtmsg_flags; - s32 rtmsg_ifindex; -}; - -static int routing_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg) -{ - int ret; - void *r = NULL; - struct in6_rtmsg r6; - struct rtentry r4; - char devname[16]; - u32 rtdev; - mm_segment_t old_fs = get_fs(); - - struct socket *mysock = sockfd_lookup(fd, &ret); - - if (mysock && mysock->sk && mysock->sk->sk_family == AF_INET6) { /* ipv6 */ - struct in6_rtmsg32 __user *ur6 = compat_ptr(arg); - ret = copy_from_user (&r6.rtmsg_dst, &(ur6->rtmsg_dst), - 3 * sizeof(struct in6_addr)); - ret |= __get_user (r6.rtmsg_type, &(ur6->rtmsg_type)); - ret |= __get_user (r6.rtmsg_dst_len, &(ur6->rtmsg_dst_len)); - ret |= __get_user (r6.rtmsg_src_len, &(ur6->rtmsg_src_len)); - ret |= __get_user (r6.rtmsg_metric, &(ur6->rtmsg_metric)); - ret |= __get_user (r6.rtmsg_info, &(ur6->rtmsg_info)); - ret |= __get_user (r6.rtmsg_flags, &(ur6->rtmsg_flags)); - ret |= __get_user (r6.rtmsg_ifindex, &(ur6->rtmsg_ifindex)); - - r = (void *) &r6; - } else { /* ipv4 */ - struct rtentry32 __user *ur4 = compat_ptr(arg); - ret = copy_from_user (&r4.rt_dst, &(ur4->rt_dst), - 3 * sizeof(struct sockaddr)); - ret |= __get_user (r4.rt_flags, &(ur4->rt_flags)); - ret |= __get_user (r4.rt_metric, &(ur4->rt_metric)); - ret |= __get_user (r4.rt_mtu, &(ur4->rt_mtu)); - ret |= __get_user (r4.rt_window, &(ur4->rt_window)); - ret |= __get_user (r4.rt_irtt, &(ur4->rt_irtt)); - ret |= __get_user (rtdev, &(ur4->rt_dev)); - if (rtdev) { - ret |= copy_from_user (devname, compat_ptr(rtdev), 15); - r4.rt_dev = devname; devname[15] = 0; - } else - r4.rt_dev = NULL; - - r = (void *) &r4; - } - - if (ret) { - ret = -EFAULT; - goto out; - } - - set_fs (KERNEL_DS); - ret = sys_ioctl (fd, cmd, (unsigned long) r); - set_fs (old_fs); - -out: - if (mysock) - sockfd_put(mysock); - - return ret; -} -#endif - #ifdef CONFIG_BLOCK typedef struct sg_io_hdr32 { compat_int_t interface_id; /* [i] 'S' for SCSI generic (required) */ @@ -1038,161 +611,6 @@ static int mt_ioctl_trans(unsigned int fd, unsigned int cmd, unsigned long arg) #endif /* CONFIG_BLOCK */ -#ifdef CONFIG_VT - -static int vt_check(struct file *file) -{ - struct tty_struct *tty; - struct inode *inode = file->f_path.dentry->d_inode; - struct vc_data *vc; - - if (file->f_op->unlocked_ioctl != tty_ioctl) - return -EINVAL; - - tty = (struct tty_struct *)file->private_data; - if (tty_paranoia_check(tty, inode, "tty_ioctl")) - return -EINVAL; - - if (tty->ops->ioctl != vt_ioctl) - return -EINVAL; - - vc = (struct vc_data *)tty->driver_data; - if (!vc_cons_allocated(vc->vc_num)) /* impossible? */ - return -ENOIOCTLCMD; - - /* - * To have permissions to do most of the vt ioctls, we either have - * to be the owner of the tty, or have CAP_SYS_TTY_CONFIG. - */ - if (current->signal->tty == tty || capable(CAP_SYS_TTY_CONFIG)) - return 1; - return 0; -} - -struct consolefontdesc32 { - unsigned short charcount; /* characters in font (256 or 512) */ - unsigned short charheight; /* scan lines per character (1-32) */ - compat_caddr_t chardata; /* font data in expanded form */ -}; - -static int do_fontx_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg, struct file *file) -{ - struct consolefontdesc32 __user *user_cfd = compat_ptr(arg); - struct console_font_op op; - compat_caddr_t data; - int i, perm; - - perm = vt_check(file); - if (perm < 0) return perm; - - switch (cmd) { - case PIO_FONTX: - if (!perm) - return -EPERM; - op.op = KD_FONT_OP_SET; - op.flags = 0; - op.width = 8; - if (get_user(op.height, &user_cfd->charheight) || - get_user(op.charcount, &user_cfd->charcount) || - get_user(data, &user_cfd->chardata)) - return -EFAULT; - op.data = compat_ptr(data); - return con_font_op(vc_cons[fg_console].d, &op); - case GIO_FONTX: - op.op = KD_FONT_OP_GET; - op.flags = 0; - op.width = 8; - if (get_user(op.height, &user_cfd->charheight) || - get_user(op.charcount, &user_cfd->charcount) || - get_user(data, &user_cfd->chardata)) - return -EFAULT; - if (!data) - return 0; - op.data = compat_ptr(data); - i = con_font_op(vc_cons[fg_console].d, &op); - if (i) - return i; - if (put_user(op.height, &user_cfd->charheight) || - put_user(op.charcount, &user_cfd->charcount) || - put_user((compat_caddr_t)(unsigned long)op.data, - &user_cfd->chardata)) - return -EFAULT; - return 0; - } - return -EINVAL; -} - -struct console_font_op32 { - compat_uint_t op; /* operation code KD_FONT_OP_* */ - compat_uint_t flags; /* KD_FONT_FLAG_* */ - compat_uint_t width, height; /* font size */ - compat_uint_t charcount; - compat_caddr_t data; /* font data with height fixed to 32 */ -}; - -static int do_kdfontop_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg, struct file *file) -{ - struct console_font_op op; - struct console_font_op32 __user *fontop = compat_ptr(arg); - int perm = vt_check(file), i; - struct vc_data *vc; - - if (perm < 0) return perm; - - if (copy_from_user(&op, fontop, sizeof(struct console_font_op32))) - return -EFAULT; - if (!perm && op.op != KD_FONT_OP_GET) - return -EPERM; - op.data = compat_ptr(((struct console_font_op32 *)&op)->data); - op.flags |= KD_FONT_FLAG_OLD; - vc = ((struct tty_struct *)file->private_data)->driver_data; - i = con_font_op(vc, &op); - if (i) - return i; - ((struct console_font_op32 *)&op)->data = (unsigned long)op.data; - if (copy_to_user(fontop, &op, sizeof(struct console_font_op32))) - return -EFAULT; - return 0; -} - -struct unimapdesc32 { - unsigned short entry_ct; - compat_caddr_t entries; -}; - -static int do_unimap_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg, struct file *file) -{ - struct unimapdesc32 tmp; - struct unimapdesc32 __user *user_ud = compat_ptr(arg); - int perm = vt_check(file); - struct vc_data *vc; - - if (perm < 0) - return perm; - if (copy_from_user(&tmp, user_ud, sizeof tmp)) - return -EFAULT; - if (tmp.entries) - if (!access_ok(VERIFY_WRITE, compat_ptr(tmp.entries), - tmp.entry_ct*sizeof(struct unipair))) - return -EFAULT; - vc = ((struct tty_struct *)file->private_data)->driver_data; - switch (cmd) { - case PIO_UNIMAP: - if (!perm) - return -EPERM; - return con_set_unimap(vc, tmp.entry_ct, - compat_ptr(tmp.entries)); - case GIO_UNIMAP: - if (!perm && fg_console != vc->vc_num) - return -EPERM; - return con_get_unimap(vc, tmp.entry_ct, &(user_ud->entry_ct), - compat_ptr(tmp.entries)); - } - return 0; -} - -#endif /* CONFIG_VT */ - static int do_smb_getmountuid(unsigned int fd, unsigned int cmd, unsigned long arg) { mm_segment_t old_fs = get_fs(); @@ -1211,176 +629,6 @@ static int do_smb_getmountuid(unsigned int fd, unsigned int cmd, unsigned long a return err; } -struct atmif_sioc32 { - compat_int_t number; - compat_int_t length; - compat_caddr_t arg; -}; - -struct atm_iobuf32 { - compat_int_t length; - compat_caddr_t buffer; -}; - -#define ATM_GETLINKRATE32 _IOW('a', ATMIOC_ITF+1, struct atmif_sioc32) -#define ATM_GETNAMES32 _IOW('a', ATMIOC_ITF+3, struct atm_iobuf32) -#define ATM_GETTYPE32 _IOW('a', ATMIOC_ITF+4, struct atmif_sioc32) -#define ATM_GETESI32 _IOW('a', ATMIOC_ITF+5, struct atmif_sioc32) -#define ATM_GETADDR32 _IOW('a', ATMIOC_ITF+6, struct atmif_sioc32) -#define ATM_RSTADDR32 _IOW('a', ATMIOC_ITF+7, struct atmif_sioc32) -#define ATM_ADDADDR32 _IOW('a', ATMIOC_ITF+8, struct atmif_sioc32) -#define ATM_DELADDR32 _IOW('a', ATMIOC_ITF+9, struct atmif_sioc32) -#define ATM_GETCIRANGE32 _IOW('a', ATMIOC_ITF+10, struct atmif_sioc32) -#define ATM_SETCIRANGE32 _IOW('a', ATMIOC_ITF+11, struct atmif_sioc32) -#define ATM_SETESI32 _IOW('a', ATMIOC_ITF+12, struct atmif_sioc32) -#define ATM_SETESIF32 _IOW('a', ATMIOC_ITF+13, struct atmif_sioc32) -#define ATM_GETSTAT32 _IOW('a', ATMIOC_SARCOM+0, struct atmif_sioc32) -#define ATM_GETSTATZ32 _IOW('a', ATMIOC_SARCOM+1, struct atmif_sioc32) -#define ATM_GETLOOP32 _IOW('a', ATMIOC_SARCOM+2, struct atmif_sioc32) -#define ATM_SETLOOP32 _IOW('a', ATMIOC_SARCOM+3, struct atmif_sioc32) -#define ATM_QUERYLOOP32 _IOW('a', ATMIOC_SARCOM+4, struct atmif_sioc32) - -static struct { - unsigned int cmd32; - unsigned int cmd; -} atm_ioctl_map[] = { - { ATM_GETLINKRATE32, ATM_GETLINKRATE }, - { ATM_GETNAMES32, ATM_GETNAMES }, - { ATM_GETTYPE32, ATM_GETTYPE }, - { ATM_GETESI32, ATM_GETESI }, - { ATM_GETADDR32, ATM_GETADDR }, - { ATM_RSTADDR32, ATM_RSTADDR }, - { ATM_ADDADDR32, ATM_ADDADDR }, - { ATM_DELADDR32, ATM_DELADDR }, - { ATM_GETCIRANGE32, ATM_GETCIRANGE }, - { ATM_SETCIRANGE32, ATM_SETCIRANGE }, - { ATM_SETESI32, ATM_SETESI }, - { ATM_SETESIF32, ATM_SETESIF }, - { ATM_GETSTAT32, ATM_GETSTAT }, - { ATM_GETSTATZ32, ATM_GETSTATZ }, - { ATM_GETLOOP32, ATM_GETLOOP }, - { ATM_SETLOOP32, ATM_SETLOOP }, - { ATM_QUERYLOOP32, ATM_QUERYLOOP } -}; - -#define NR_ATM_IOCTL ARRAY_SIZE(atm_ioctl_map) - -static int do_atm_iobuf(unsigned int fd, unsigned int cmd, unsigned long arg) -{ - struct atm_iobuf __user *iobuf; - struct atm_iobuf32 __user *iobuf32; - u32 data; - void __user *datap; - int len, err; - - iobuf = compat_alloc_user_space(sizeof(*iobuf)); - iobuf32 = compat_ptr(arg); - - if (get_user(len, &iobuf32->length) || - get_user(data, &iobuf32->buffer)) - return -EFAULT; - datap = compat_ptr(data); - if (put_user(len, &iobuf->length) || - put_user(datap, &iobuf->buffer)) - return -EFAULT; - - err = sys_ioctl(fd, cmd, (unsigned long)iobuf); - - if (!err) { - if (copy_in_user(&iobuf32->length, &iobuf->length, - sizeof(int))) - err = -EFAULT; - } - - return err; -} - -static int do_atmif_sioc(unsigned int fd, unsigned int cmd, unsigned long arg) -{ - struct atmif_sioc __user *sioc; - struct atmif_sioc32 __user *sioc32; - u32 data; - void __user *datap; - int err; - - sioc = compat_alloc_user_space(sizeof(*sioc)); - sioc32 = compat_ptr(arg); - - if (copy_in_user(&sioc->number, &sioc32->number, 2 * sizeof(int)) || - get_user(data, &sioc32->arg)) - return -EFAULT; - datap = compat_ptr(data); - if (put_user(datap, &sioc->arg)) - return -EFAULT; - - err = sys_ioctl(fd, cmd, (unsigned long) sioc); - - if (!err) { - if (copy_in_user(&sioc32->length, &sioc->length, - sizeof(int))) - err = -EFAULT; - } - return err; -} - -static int do_atm_ioctl(unsigned int fd, unsigned int cmd32, unsigned long arg) -{ - int i; - unsigned int cmd = 0; - - switch (cmd32) { - case SONET_GETSTAT: - case SONET_GETSTATZ: - case SONET_GETDIAG: - case SONET_SETDIAG: - case SONET_CLRDIAG: - case SONET_SETFRAMING: - case SONET_GETFRAMING: - case SONET_GETFRSENSE: - return do_atmif_sioc(fd, cmd32, arg); - } - - for (i = 0; i < NR_ATM_IOCTL; i++) { - if (cmd32 == atm_ioctl_map[i].cmd32) { - cmd = atm_ioctl_map[i].cmd; - break; - } - } - if (i == NR_ATM_IOCTL) - return -EINVAL; - - switch (cmd) { - case ATM_GETNAMES: - return do_atm_iobuf(fd, cmd, arg); - - case ATM_GETLINKRATE: - case ATM_GETTYPE: - case ATM_GETESI: - case ATM_GETADDR: - case ATM_RSTADDR: - case ATM_ADDADDR: - case ATM_DELADDR: - case ATM_GETCIRANGE: - case ATM_SETCIRANGE: - case ATM_SETESI: - case ATM_SETESIF: - case ATM_GETSTAT: - case ATM_GETSTATZ: - case ATM_GETLOOP: - case ATM_SETLOOP: - case ATM_QUERYLOOP: - return do_atmif_sioc(fd, cmd, arg); - } - - return -EINVAL; -} - -static __used int -ret_einval(unsigned int fd, unsigned int cmd, unsigned long arg) -{ - return -EINVAL; -} - static int ioc_settimeout(unsigned int fd, unsigned int cmd, unsigned long arg) { return rw_long(fd, AUTOFS_IOC_SETTIMEOUT, arg); @@ -1717,21 +965,6 @@ static int do_i2c_smbus_ioctl(unsigned int fd, unsigned int cmd, unsigned long a return sys_ioctl(fd, cmd, (unsigned long)tdata); } -/* Since old style bridge ioctl's endup using SIOCDEVPRIVATE - * for some operations; this forces use of the newer bridge-utils that - * use compatible ioctls - */ -static int old_bridge_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg) -{ - u32 tmp; - - if (get_user(tmp, (u32 __user *) arg)) - return -EFAULT; - if (tmp == BRCTL_GET_VERSION) - return BRCTL_VERSION + 1; - return -EINVAL; -} - #define RTC_IRQP_READ32 _IOR('p', 0x0b, compat_ulong_t) #define RTC_IRQP_SET32 _IOW('p', 0x0c, compat_ulong_t) #define RTC_EPOCH_READ32 _IOR('p', 0x0d, compat_ulong_t) @@ -1799,7 +1032,7 @@ struct space_resv_32 { /* just account for different alignment */ static int compat_ioctl_preallocate(struct file *file, unsigned long arg) { - struct space_resv_32 __user *p32 = (void __user *)arg; + struct space_resv_32 __user *p32 = compat_ptr(arg); struct space_resv __user *p = compat_alloc_user_space(sizeof(*p)); if (copy_in_user(&p->l_type, &p32->l_type, sizeof(s16)) || @@ -1816,25 +1049,13 @@ static int compat_ioctl_preallocate(struct file *file, unsigned long arg) #endif -typedef int (*ioctl_trans_handler_t)(unsigned int, unsigned int, - unsigned long, struct file *); - struct ioctl_trans { unsigned long cmd; - ioctl_trans_handler_t handler; struct ioctl_trans *next; }; -#define HANDLE_IOCTL(cmd,handler) \ - { (cmd), (ioctl_trans_handler_t)(handler) }, - /* pointer to compatible structure or no argument */ -#define COMPATIBLE_IOCTL(cmd) \ - { (cmd), do_ioctl32_pointer }, - -/* argument is an unsigned long integer, not a pointer */ -#define ULONG_IOCTL(cmd) \ - { (cmd), (ioctl_trans_handler_t)sys_ioctl }, +#define COMPATIBLE_IOCTL(cmd) { (cmd), }, /* ioctl should not be warned about even if it's not implemented. Valid reasons to use this: @@ -1856,7 +1077,6 @@ COMPATIBLE_IOCTL(TCSETA) COMPATIBLE_IOCTL(TCSETAW) COMPATIBLE_IOCTL(TCSETAF) COMPATIBLE_IOCTL(TCSBRK) -ULONG_IOCTL(TCSBRKP) COMPATIBLE_IOCTL(TCXONC) COMPATIBLE_IOCTL(TCFLSH) COMPATIBLE_IOCTL(TCGETS) @@ -1866,7 +1086,6 @@ COMPATIBLE_IOCTL(TCSETSF) COMPATIBLE_IOCTL(TIOCLINUX) COMPATIBLE_IOCTL(TIOCSBRK) COMPATIBLE_IOCTL(TIOCCBRK) -ULONG_IOCTL(TIOCMIWAIT) COMPATIBLE_IOCTL(TIOCGICOUNT) /* Little t */ COMPATIBLE_IOCTL(TIOCGETD) @@ -1888,7 +1107,6 @@ COMPATIBLE_IOCTL(TIOCSTI) COMPATIBLE_IOCTL(TIOCOUTQ) COMPATIBLE_IOCTL(TIOCSPGRP) COMPATIBLE_IOCTL(TIOCGPGRP) -ULONG_IOCTL(TIOCSCTTY) COMPATIBLE_IOCTL(TIOCGPTN) COMPATIBLE_IOCTL(TIOCSPTLCK) COMPATIBLE_IOCTL(TIOCSERGETLSR) @@ -1904,6 +1122,7 @@ COMPATIBLE_IOCTL(FIONCLEX) COMPATIBLE_IOCTL(FIOASYNC) COMPATIBLE_IOCTL(FIONBIO) COMPATIBLE_IOCTL(FIONREAD) /* This is also TIOCINQ */ +COMPATIBLE_IOCTL(FS_IOC_FIEMAP) /* 0x00 */ COMPATIBLE_IOCTL(FIBMAP) COMPATIBLE_IOCTL(FIGETBSZ) @@ -1918,36 +1137,21 @@ COMPATIBLE_IOCTL(PRINT_RAID_DEBUG) COMPATIBLE_IOCTL(RAID_AUTORUN) COMPATIBLE_IOCTL(CLEAR_ARRAY) COMPATIBLE_IOCTL(ADD_NEW_DISK) -ULONG_IOCTL(HOT_REMOVE_DISK) COMPATIBLE_IOCTL(SET_ARRAY_INFO) COMPATIBLE_IOCTL(SET_DISK_INFO) COMPATIBLE_IOCTL(WRITE_RAID_INFO) COMPATIBLE_IOCTL(UNPROTECT_ARRAY) COMPATIBLE_IOCTL(PROTECT_ARRAY) -ULONG_IOCTL(HOT_ADD_DISK) -ULONG_IOCTL(SET_DISK_FAULTY) COMPATIBLE_IOCTL(RUN_ARRAY) COMPATIBLE_IOCTL(STOP_ARRAY) COMPATIBLE_IOCTL(STOP_ARRAY_RO) COMPATIBLE_IOCTL(RESTART_ARRAY_RW) COMPATIBLE_IOCTL(GET_BITMAP_FILE) -ULONG_IOCTL(SET_BITMAP_FILE) -/* Big K */ -COMPATIBLE_IOCTL(PIO_FONT) -COMPATIBLE_IOCTL(GIO_FONT) -COMPATIBLE_IOCTL(PIO_CMAP) -COMPATIBLE_IOCTL(GIO_CMAP) -ULONG_IOCTL(KDSIGACCEPT) COMPATIBLE_IOCTL(KDGETKEYCODE) COMPATIBLE_IOCTL(KDSETKEYCODE) -ULONG_IOCTL(KIOCSOUND) -ULONG_IOCTL(KDMKTONE) COMPATIBLE_IOCTL(KDGKBTYPE) -ULONG_IOCTL(KDSETMODE) COMPATIBLE_IOCTL(KDGETMODE) -ULONG_IOCTL(KDSKBMODE) COMPATIBLE_IOCTL(KDGKBMODE) -ULONG_IOCTL(KDSKBMETA) COMPATIBLE_IOCTL(KDGKBMETA) COMPATIBLE_IOCTL(KDGKBENT) COMPATIBLE_IOCTL(KDSKBENT) @@ -1957,15 +1161,7 @@ COMPATIBLE_IOCTL(KDGKBDIACR) COMPATIBLE_IOCTL(KDSKBDIACR) COMPATIBLE_IOCTL(KDKBDREP) COMPATIBLE_IOCTL(KDGKBLED) -ULONG_IOCTL(KDSKBLED) COMPATIBLE_IOCTL(KDGETLED) -ULONG_IOCTL(KDSETLED) -COMPATIBLE_IOCTL(GIO_SCRNMAP) -COMPATIBLE_IOCTL(PIO_SCRNMAP) -COMPATIBLE_IOCTL(GIO_UNISCRNMAP) -COMPATIBLE_IOCTL(PIO_UNISCRNMAP) -COMPATIBLE_IOCTL(PIO_FONTRESET) -COMPATIBLE_IOCTL(PIO_UNIMAPCLR) #ifdef CONFIG_BLOCK /* Big S */ COMPATIBLE_IOCTL(SCSI_IOCTL_GET_IDLUN) @@ -1977,32 +1173,6 @@ COMPATIBLE_IOCTL(SCSI_IOCTL_SEND_COMMAND) COMPATIBLE_IOCTL(SCSI_IOCTL_PROBE_HOST) COMPATIBLE_IOCTL(SCSI_IOCTL_GET_PCI) #endif -/* Big T */ -COMPATIBLE_IOCTL(TUNSETNOCSUM) -COMPATIBLE_IOCTL(TUNSETDEBUG) -COMPATIBLE_IOCTL(TUNSETPERSIST) -COMPATIBLE_IOCTL(TUNSETOWNER) -COMPATIBLE_IOCTL(TUNSETLINK) -COMPATIBLE_IOCTL(TUNSETGROUP) -COMPATIBLE_IOCTL(TUNGETFEATURES) -COMPATIBLE_IOCTL(TUNSETOFFLOAD) -COMPATIBLE_IOCTL(TUNSETTXFILTER) -COMPATIBLE_IOCTL(TUNGETSNDBUF) -COMPATIBLE_IOCTL(TUNSETSNDBUF) -/* Big V */ -COMPATIBLE_IOCTL(VT_SETMODE) -COMPATIBLE_IOCTL(VT_GETMODE) -COMPATIBLE_IOCTL(VT_GETSTATE) -COMPATIBLE_IOCTL(VT_OPENQRY) -ULONG_IOCTL(VT_ACTIVATE) -ULONG_IOCTL(VT_WAITACTIVE) -ULONG_IOCTL(VT_RELDISP) -ULONG_IOCTL(VT_DISALLOCATE) -COMPATIBLE_IOCTL(VT_RESIZE) -COMPATIBLE_IOCTL(VT_RESIZEX) -COMPATIBLE_IOCTL(VT_LOCKSWITCH) -COMPATIBLE_IOCTL(VT_UNLOCKSWITCH) -COMPATIBLE_IOCTL(VT_GETHIFONTMASK) /* Little p (/dev/rtc, /dev/envctrl, etc.) */ COMPATIBLE_IOCTL(RTC_AIE_ON) COMPATIBLE_IOCTL(RTC_AIE_OFF) @@ -2030,36 +1200,13 @@ COMPATIBLE_IOCTL(_IOW('p', 21, int[7])) /* RTCSET */ COMPATIBLE_IOCTL(MTIOCTOP) /* Socket level stuff */ COMPATIBLE_IOCTL(FIOQSIZE) -COMPATIBLE_IOCTL(FIOSETOWN) -COMPATIBLE_IOCTL(SIOCSPGRP) -COMPATIBLE_IOCTL(FIOGETOWN) -COMPATIBLE_IOCTL(SIOCGPGRP) -COMPATIBLE_IOCTL(SIOCATMARK) -COMPATIBLE_IOCTL(SIOCSIFLINK) -COMPATIBLE_IOCTL(SIOCSIFENCAP) -COMPATIBLE_IOCTL(SIOCGIFENCAP) -COMPATIBLE_IOCTL(SIOCSIFNAME) -COMPATIBLE_IOCTL(SIOCSARP) -COMPATIBLE_IOCTL(SIOCGARP) -COMPATIBLE_IOCTL(SIOCDARP) -COMPATIBLE_IOCTL(SIOCSRARP) -COMPATIBLE_IOCTL(SIOCGRARP) -COMPATIBLE_IOCTL(SIOCDRARP) -COMPATIBLE_IOCTL(SIOCADDDLCI) -COMPATIBLE_IOCTL(SIOCDELDLCI) -COMPATIBLE_IOCTL(SIOCGMIIPHY) -COMPATIBLE_IOCTL(SIOCGMIIREG) -COMPATIBLE_IOCTL(SIOCSMIIREG) -COMPATIBLE_IOCTL(SIOCGIFVLAN) -COMPATIBLE_IOCTL(SIOCSIFVLAN) -COMPATIBLE_IOCTL(SIOCBRADDBR) -COMPATIBLE_IOCTL(SIOCBRDELBR) #ifdef CONFIG_BLOCK +/* loop */ +IGNORE_IOCTL(LOOP_CLR_FD) /* SG stuff */ COMPATIBLE_IOCTL(SG_SET_TIMEOUT) COMPATIBLE_IOCTL(SG_GET_TIMEOUT) COMPATIBLE_IOCTL(SG_EMULATED_HOST) -ULONG_IOCTL(SG_SET_TRANSFORM) COMPATIBLE_IOCTL(SG_GET_TRANSFORM) COMPATIBLE_IOCTL(SG_SET_RESERVED_SIZE) COMPATIBLE_IOCTL(SG_GET_RESERVED_SIZE) @@ -2296,8 +1443,6 @@ COMPATIBLE_IOCTL(SOUND_MIXER_GETLEVELS) COMPATIBLE_IOCTL(SOUND_MIXER_SETLEVELS) COMPATIBLE_IOCTL(OSS_GETVERSION) /* AUTOFS */ -ULONG_IOCTL(AUTOFS_IOC_READY) -ULONG_IOCTL(AUTOFS_IOC_FAIL) COMPATIBLE_IOCTL(AUTOFS_IOC_CATATONIC) COMPATIBLE_IOCTL(AUTOFS_IOC_PROTOVER) COMPATIBLE_IOCTL(AUTOFS_IOC_EXPIRE) @@ -2309,22 +1454,6 @@ COMPATIBLE_IOCTL(RAW_SETBIND) COMPATIBLE_IOCTL(RAW_GETBIND) /* SMB ioctls which do not need any translations */ COMPATIBLE_IOCTL(SMB_IOC_NEWCONN) -/* Little a */ -COMPATIBLE_IOCTL(ATMSIGD_CTRL) -COMPATIBLE_IOCTL(ATMARPD_CTRL) -COMPATIBLE_IOCTL(ATMLEC_CTRL) -COMPATIBLE_IOCTL(ATMLEC_MCAST) -COMPATIBLE_IOCTL(ATMLEC_DATA) -COMPATIBLE_IOCTL(ATM_SETSC) -COMPATIBLE_IOCTL(SIOCSIFATMTCP) -COMPATIBLE_IOCTL(SIOCMKCLIP) -COMPATIBLE_IOCTL(ATMARP_MKIP) -COMPATIBLE_IOCTL(ATMARP_SETENTRY) -COMPATIBLE_IOCTL(ATMARP_ENCAP) -COMPATIBLE_IOCTL(ATMTCP_CREATE) -COMPATIBLE_IOCTL(ATMTCP_REMOVE) -COMPATIBLE_IOCTL(ATMMPC_CTRL) -COMPATIBLE_IOCTL(ATMMPC_DATA) /* Watchdog */ COMPATIBLE_IOCTL(WDIOC_GETSUPPORT) COMPATIBLE_IOCTL(WDIOC_GETSTATUS) @@ -2422,14 +1551,10 @@ COMPATIBLE_IOCTL(USBDEVFS_REAPURB32) COMPATIBLE_IOCTL(USBDEVFS_REAPURBNDELAY32) COMPATIBLE_IOCTL(USBDEVFS_CLEAR_HALT) /* NBD */ -ULONG_IOCTL(NBD_SET_SOCK) -ULONG_IOCTL(NBD_SET_BLKSIZE) -ULONG_IOCTL(NBD_SET_SIZE) COMPATIBLE_IOCTL(NBD_DO_IT) COMPATIBLE_IOCTL(NBD_CLEAR_SOCK) COMPATIBLE_IOCTL(NBD_CLEAR_QUE) COMPATIBLE_IOCTL(NBD_PRINT_DEBUG) -ULONG_IOCTL(NBD_SET_SIZE_BLOCKS) COMPATIBLE_IOCTL(NBD_DISCONNECT) /* i2c */ COMPATIBLE_IOCTL(I2C_SLAVE) @@ -2529,131 +1654,13 @@ COMPATIBLE_IOCTL(JSIOCGAXES) COMPATIBLE_IOCTL(JSIOCGBUTTONS) COMPATIBLE_IOCTL(JSIOCGNAME(0)) -/* now things that need handlers */ -#ifdef CONFIG_NET -HANDLE_IOCTL(SIOCGIFNAME, dev_ifname32) -HANDLE_IOCTL(SIOCGIFCONF, dev_ifconf) -HANDLE_IOCTL(SIOCGIFFLAGS, dev_ifsioc) -HANDLE_IOCTL(SIOCSIFFLAGS, dev_ifsioc) -HANDLE_IOCTL(SIOCGIFMETRIC, dev_ifsioc) -HANDLE_IOCTL(SIOCSIFMETRIC, dev_ifsioc) -HANDLE_IOCTL(SIOCGIFMTU, dev_ifsioc) -HANDLE_IOCTL(SIOCSIFMTU, dev_ifsioc) -HANDLE_IOCTL(SIOCGIFMEM, dev_ifsioc) -HANDLE_IOCTL(SIOCSIFMEM, dev_ifsioc) -HANDLE_IOCTL(SIOCGIFHWADDR, dev_ifsioc) -HANDLE_IOCTL(SIOCSIFHWADDR, dev_ifsioc) -HANDLE_IOCTL(SIOCADDMULTI, dev_ifsioc) -HANDLE_IOCTL(SIOCDELMULTI, dev_ifsioc) -HANDLE_IOCTL(SIOCGIFINDEX, dev_ifsioc) -HANDLE_IOCTL(SIOCGIFMAP, dev_ifsioc) -HANDLE_IOCTL(SIOCSIFMAP, dev_ifsioc) -HANDLE_IOCTL(SIOCGIFADDR, dev_ifsioc) -HANDLE_IOCTL(SIOCSIFADDR, dev_ifsioc) -HANDLE_IOCTL(SIOCSIFHWBROADCAST, dev_ifsioc) -HANDLE_IOCTL(SIOCSHWTSTAMP, dev_ifsioc) - -/* ioctls used by appletalk ddp.c */ -HANDLE_IOCTL(SIOCATALKDIFADDR, dev_ifsioc) -HANDLE_IOCTL(SIOCDIFADDR, dev_ifsioc) -HANDLE_IOCTL(SIOCSARP, dev_ifsioc) -HANDLE_IOCTL(SIOCDARP, dev_ifsioc) - -HANDLE_IOCTL(SIOCGIFBRDADDR, dev_ifsioc) -HANDLE_IOCTL(SIOCSIFBRDADDR, dev_ifsioc) -HANDLE_IOCTL(SIOCGIFDSTADDR, dev_ifsioc) -HANDLE_IOCTL(SIOCSIFDSTADDR, dev_ifsioc) -HANDLE_IOCTL(SIOCGIFNETMASK, dev_ifsioc) -HANDLE_IOCTL(SIOCSIFNETMASK, dev_ifsioc) -HANDLE_IOCTL(SIOCSIFPFLAGS, dev_ifsioc) -HANDLE_IOCTL(SIOCGIFPFLAGS, dev_ifsioc) -HANDLE_IOCTL(SIOCGIFTXQLEN, dev_ifsioc) -HANDLE_IOCTL(SIOCSIFTXQLEN, dev_ifsioc) -HANDLE_IOCTL(TUNSETIFF, dev_ifsioc) -HANDLE_IOCTL(TUNGETIFF, dev_ifsioc) -HANDLE_IOCTL(SIOCETHTOOL, ethtool_ioctl) -HANDLE_IOCTL(SIOCBONDENSLAVE, bond_ioctl) -HANDLE_IOCTL(SIOCBONDRELEASE, bond_ioctl) -HANDLE_IOCTL(SIOCBONDSETHWADDR, bond_ioctl) -HANDLE_IOCTL(SIOCBONDSLAVEINFOQUERY, bond_ioctl) -HANDLE_IOCTL(SIOCBONDINFOQUERY, bond_ioctl) -HANDLE_IOCTL(SIOCBONDCHANGEACTIVE, bond_ioctl) -HANDLE_IOCTL(SIOCADDRT, routing_ioctl) -HANDLE_IOCTL(SIOCDELRT, routing_ioctl) -HANDLE_IOCTL(SIOCBRADDIF, dev_ifsioc) -HANDLE_IOCTL(SIOCBRDELIF, dev_ifsioc) -/* Note SIOCRTMSG is no longer, so this is safe and * the user would have seen just an -EINVAL anyways. */ -HANDLE_IOCTL(SIOCRTMSG, ret_einval) -HANDLE_IOCTL(SIOCGSTAMP, do_siocgstamp) -HANDLE_IOCTL(SIOCGSTAMPNS, do_siocgstampns) -#endif -#ifdef CONFIG_BLOCK -HANDLE_IOCTL(SG_IO,sg_ioctl_trans) -HANDLE_IOCTL(SG_GET_REQUEST_TABLE, sg_grt_trans) -#endif -HANDLE_IOCTL(PPPIOCGIDLE32, ppp_ioctl_trans) -HANDLE_IOCTL(PPPIOCSCOMPRESS32, ppp_ioctl_trans) -HANDLE_IOCTL(PPPIOCSPASS32, ppp_sock_fprog_ioctl_trans) -HANDLE_IOCTL(PPPIOCSACTIVE32, ppp_sock_fprog_ioctl_trans) -#ifdef CONFIG_BLOCK -HANDLE_IOCTL(MTIOCGET32, mt_ioctl_trans) -HANDLE_IOCTL(MTIOCPOS32, mt_ioctl_trans) -#endif -#define AUTOFS_IOC_SETTIMEOUT32 _IOWR(0x93,0x64,unsigned int) -HANDLE_IOCTL(AUTOFS_IOC_SETTIMEOUT32, ioc_settimeout) -#ifdef CONFIG_VT -HANDLE_IOCTL(PIO_FONTX, do_fontx_ioctl) -HANDLE_IOCTL(GIO_FONTX, do_fontx_ioctl) -HANDLE_IOCTL(PIO_UNIMAP, do_unimap_ioctl) -HANDLE_IOCTL(GIO_UNIMAP, do_unimap_ioctl) -HANDLE_IOCTL(KDFONTOP, do_kdfontop_ioctl) -#endif -/* One SMB ioctl needs translations. */ -#define SMB_IOC_GETMOUNTUID_32 _IOR('u', 1, compat_uid_t) -HANDLE_IOCTL(SMB_IOC_GETMOUNTUID_32, do_smb_getmountuid) -HANDLE_IOCTL(ATM_GETLINKRATE32, do_atm_ioctl) -HANDLE_IOCTL(ATM_GETNAMES32, do_atm_ioctl) -HANDLE_IOCTL(ATM_GETTYPE32, do_atm_ioctl) -HANDLE_IOCTL(ATM_GETESI32, do_atm_ioctl) -HANDLE_IOCTL(ATM_GETADDR32, do_atm_ioctl) -HANDLE_IOCTL(ATM_RSTADDR32, do_atm_ioctl) -HANDLE_IOCTL(ATM_ADDADDR32, do_atm_ioctl) -HANDLE_IOCTL(ATM_DELADDR32, do_atm_ioctl) -HANDLE_IOCTL(ATM_GETCIRANGE32, do_atm_ioctl) -HANDLE_IOCTL(ATM_SETCIRANGE32, do_atm_ioctl) -HANDLE_IOCTL(ATM_SETESI32, do_atm_ioctl) -HANDLE_IOCTL(ATM_SETESIF32, do_atm_ioctl) -HANDLE_IOCTL(ATM_GETSTAT32, do_atm_ioctl) -HANDLE_IOCTL(ATM_GETSTATZ32, do_atm_ioctl) -HANDLE_IOCTL(ATM_GETLOOP32, do_atm_ioctl) -HANDLE_IOCTL(ATM_SETLOOP32, do_atm_ioctl) -HANDLE_IOCTL(ATM_QUERYLOOP32, do_atm_ioctl) -HANDLE_IOCTL(SONET_GETSTAT, do_atm_ioctl) -HANDLE_IOCTL(SONET_GETSTATZ, do_atm_ioctl) -HANDLE_IOCTL(SONET_GETDIAG, do_atm_ioctl) -HANDLE_IOCTL(SONET_SETDIAG, do_atm_ioctl) -HANDLE_IOCTL(SONET_CLRDIAG, do_atm_ioctl) -HANDLE_IOCTL(SONET_SETFRAMING, do_atm_ioctl) -HANDLE_IOCTL(SONET_GETFRAMING, do_atm_ioctl) -HANDLE_IOCTL(SONET_GETFRSENSE, do_atm_ioctl) -/* block stuff */ -#ifdef CONFIG_BLOCK -/* loop */ -IGNORE_IOCTL(LOOP_CLR_FD) -/* Raw devices */ -HANDLE_IOCTL(RAW_SETBIND, raw_ioctl) -HANDLE_IOCTL(RAW_GETBIND, raw_ioctl) -#endif -/* Serial */ -HANDLE_IOCTL(TIOCGSERIAL, serial_struct_ioctl) -HANDLE_IOCTL(TIOCSSERIAL, serial_struct_ioctl) #ifdef TIOCGLTC COMPATIBLE_IOCTL(TIOCGLTC) COMPATIBLE_IOCTL(TIOCSLTC) #endif #ifdef TIOCSTART /* - * For these two we have defintions in ioctls.h and/or termios.h on + * For these two we have definitions in ioctls.h and/or termios.h on * some architectures but no actual implemention. Some applications * like bash call them if they are defined in the headers, so we provide * entries here to avoid syslog message spew. @@ -2662,28 +1669,7 @@ COMPATIBLE_IOCTL(TIOCSTART) COMPATIBLE_IOCTL(TIOCSTOP) #endif /* Usbdevfs */ -HANDLE_IOCTL(USBDEVFS_CONTROL32, do_usbdevfs_control) -HANDLE_IOCTL(USBDEVFS_BULK32, do_usbdevfs_bulk) -HANDLE_IOCTL(USBDEVFS_DISCSIGNAL32, do_usbdevfs_discsignal) COMPATIBLE_IOCTL(USBDEVFS_IOCTL32) -/* i2c */ -HANDLE_IOCTL(I2C_FUNCS, w_long) -HANDLE_IOCTL(I2C_RDWR, do_i2c_rdwr_ioctl) -HANDLE_IOCTL(I2C_SMBUS, do_i2c_smbus_ioctl) -/* bridge */ -HANDLE_IOCTL(SIOCSIFBR, old_bridge_ioctl) -HANDLE_IOCTL(SIOCGIFBR, old_bridge_ioctl) -/* Not implemented in the native kernel */ -IGNORE_IOCTL(SIOCGIFCOUNT) -HANDLE_IOCTL(RTC_IRQP_READ32, rtc_ioctl) -HANDLE_IOCTL(RTC_IRQP_SET32, rtc_ioctl) -HANDLE_IOCTL(RTC_EPOCH_READ32, rtc_ioctl) -HANDLE_IOCTL(RTC_EPOCH_SET32, rtc_ioctl) - -/* dvb */ -HANDLE_IOCTL(VIDEO_GET_EVENT, do_video_get_event) -HANDLE_IOCTL(VIDEO_STILLPICTURE, do_video_stillpicture) -HANDLE_IOCTL(VIDEO_SET_SPU_PALETTE, do_video_set_spu_palette) /* parport */ COMPATIBLE_IOCTL(LPTIME) @@ -2697,7 +1683,6 @@ COMPATIBLE_IOCTL(LPGETSTATUS) COMPATIBLE_IOCTL(LPRESET) /*LPGETSTATS not implemented, but no kernels seem to compile it in anyways*/ COMPATIBLE_IOCTL(LPGETFLAGS) -HANDLE_IOCTL(LPSETTIMEOUT, lp_timeout_trans) /* fat 'r' ioctls. These are handled by fat with ->compat_ioctl, but we don't want warnings on other file systems. So declare @@ -2733,6 +1718,120 @@ static inline unsigned long ioctl32_hash(unsigned long cmd) return (((cmd >> 6) ^ (cmd >> 4) ^ cmd)) % IOCTL_HASHSIZE; } +/* + * Convert common ioctl arguments based on their command number + * + * Please do not add any code in here. Instead, implement + * a compat_ioctl operation in the place that handleѕ the + * ioctl for the native case. + */ +static long do_ioctl_trans(int fd, unsigned int cmd, + unsigned long arg, struct file *file) +{ + switch (cmd) { + case PPPIOCGIDLE32: + case PPPIOCSCOMPRESS32: + return ppp_ioctl_trans(fd, cmd, arg); + case PPPIOCSPASS32: + case PPPIOCSACTIVE32: + return ppp_sock_fprog_ioctl_trans(fd, cmd, arg); +#ifdef CONFIG_BLOCK + case SG_IO: + return sg_ioctl_trans(fd, cmd, arg); + case SG_GET_REQUEST_TABLE: + return sg_grt_trans(fd, cmd, arg); + case MTIOCGET32: + case MTIOCPOS32: + return mt_ioctl_trans(fd, cmd, arg); + /* Raw devices */ + case RAW_SETBIND: + case RAW_GETBIND: + return raw_ioctl(fd, cmd, arg); +#endif +#define AUTOFS_IOC_SETTIMEOUT32 _IOWR(0x93,0x64,unsigned int) + case AUTOFS_IOC_SETTIMEOUT32: + return ioc_settimeout(fd, cmd, arg); + /* One SMB ioctl needs translations. */ +#define SMB_IOC_GETMOUNTUID_32 _IOR('u', 1, compat_uid_t) + case SMB_IOC_GETMOUNTUID_32: + return do_smb_getmountuid(fd, cmd, arg); + /* Serial */ + case TIOCGSERIAL: + case TIOCSSERIAL: + return serial_struct_ioctl(fd, cmd, arg); + /* Usbdevfs */ + case USBDEVFS_CONTROL32: + return do_usbdevfs_control(fd, cmd, arg); + case USBDEVFS_BULK32: + return do_usbdevfs_bulk(fd, cmd, arg); + case USBDEVFS_DISCSIGNAL32: + return do_usbdevfs_discsignal(fd, cmd, arg); + /* i2c */ + case I2C_FUNCS: + return w_long(fd, cmd, arg); + case I2C_RDWR: + return do_i2c_rdwr_ioctl(fd, cmd, arg); + case I2C_SMBUS: + return do_i2c_smbus_ioctl(fd, cmd, arg); + /* Not implemented in the native kernel */ + case RTC_IRQP_READ32: + case RTC_IRQP_SET32: + case RTC_EPOCH_READ32: + case RTC_EPOCH_SET32: + return rtc_ioctl(fd, cmd, arg); + + /* dvb */ + case VIDEO_GET_EVENT: + return do_video_get_event(fd, cmd, arg); + case VIDEO_STILLPICTURE: + return do_video_stillpicture(fd, cmd, arg); + case VIDEO_SET_SPU_PALETTE: + return do_video_set_spu_palette(fd, cmd, arg); + + /* lp */ + case LPSETTIMEOUT: + return lp_timeout_trans(fd, cmd, arg); + } + + /* + * These take an integer instead of a pointer as 'arg', + * so we must not do a compat_ptr() translation. + */ + switch (cmd) { + /* Big T */ + case TCSBRKP: + case TIOCMIWAIT: + case TIOCSCTTY: + /* RAID */ + case HOT_REMOVE_DISK: + case HOT_ADD_DISK: + case SET_DISK_FAULTY: + case SET_BITMAP_FILE: + /* Big K */ + case KDSIGACCEPT: + case KIOCSOUND: + case KDMKTONE: + case KDSETMODE: + case KDSKBMODE: + case KDSKBMETA: + case KDSKBLED: + case KDSETLED: + /* SG stuff */ + case SG_SET_TRANSFORM: + /* AUTOFS */ + case AUTOFS_IOC_READY: + case AUTOFS_IOC_FAIL: + /* NBD */ + case NBD_SET_SOCK: + case NBD_SET_BLKSIZE: + case NBD_SET_SIZE: + case NBD_SET_SIZE_BLOCKS: + return do_vfs_ioctl(file, fd, cmd, arg); + } + + return -ENOIOCTLCMD; +} + static void compat_ioctl_error(struct file *filp, unsigned int fd, unsigned int cmd, unsigned long arg) { @@ -2800,7 +1899,7 @@ asmlinkage long compat_sys_ioctl(unsigned int fd, unsigned int cmd, #else case FS_IOC_RESVSP: case FS_IOC_RESVSP64: - error = ioctl_preallocate(filp, (void __user *)arg); + error = ioctl_preallocate(filp, compat_ptr(arg)); goto out_fput; #endif @@ -2829,13 +1928,8 @@ asmlinkage long compat_sys_ioctl(unsigned int fd, unsigned int cmd, goto found_handler; } -#ifdef CONFIG_NET - if (S_ISSOCK(filp->f_path.dentry->d_inode->i_mode) && - cmd >= SIOCDEVPRIVATE && cmd <= (SIOCDEVPRIVATE + 15)) { - error = siocdevprivate_ioctl(fd, cmd, arg); - } else -#endif - { + error = do_ioctl_trans(fd, cmd, arg, filp); + if (error == -ENOIOCTLCMD) { static int count; if (++count <= 50) @@ -2846,13 +1940,7 @@ asmlinkage long compat_sys_ioctl(unsigned int fd, unsigned int cmd, goto out_fput; found_handler: - if (t->handler) { - lock_kernel(); - error = t->handler(fd, cmd, arg, filp); - unlock_kernel(); - goto out_fput; - } - + arg = (unsigned long)compat_ptr(arg); do_ioctl: error = do_vfs_ioctl(filp, fd, cmd, arg); out_fput: