aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2009-12-11 23:57:46 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2009-12-11 23:57:46 -0500
commit92340ee3198a2afd7664ed2f5472fa072b15fa32 (patch)
treeb77411ace423d8702da51938c953914d341fba80 /fs
parenta1c36e52068a59374e127d60e4d8f4377072fc98 (diff)
parent637e8a60a7aaf4ef7d46cfdf83bcfac9cf6f0fbd (diff)
Merge branch 'compat-ioctl-merge' of git://git.kernel.org/pub/scm/linux/kernel/git/arnd/playground
* 'compat-ioctl-merge' of git://git.kernel.org/pub/scm/linux/kernel/git/arnd/playground: usbdevfs: move compat_ioctl handling to devio.c lp: move compat_ioctl handling into lp.c compat_ioctl: pass compat pointer directly to handlers compat_ioctl: simplify lookup table compat_ioctl: simplify calling of handlers compat_ioctl: inline all conversion handlers compat_ioctl: Remove BKL compat_ioctl: remove all VT ioctl handling
Diffstat (limited to 'fs')
-rw-r--r--fs/compat_ioctl.c767
1 files changed, 203 insertions, 564 deletions
diff --git a/fs/compat_ioctl.c b/fs/compat_ioctl.c
index 2346895b3a77..278020d2449c 100644
--- a/fs/compat_ioctl.c
+++ b/fs/compat_ioctl.c
@@ -111,43 +111,40 @@
111#include <linux/dvb/frontend.h> 111#include <linux/dvb/frontend.h>
112#include <linux/dvb/video.h> 112#include <linux/dvb/video.h>
113 113
114#include <linux/sort.h>
115
114#ifdef CONFIG_SPARC 116#ifdef CONFIG_SPARC
115#include <asm/fbio.h> 117#include <asm/fbio.h>
116#endif 118#endif
117 119
118static int do_ioctl32_pointer(unsigned int fd, unsigned int cmd, 120static int w_long(unsigned int fd, unsigned int cmd,
119 unsigned long arg, struct file *f) 121 compat_ulong_t __user *argp)
120{
121 return sys_ioctl(fd, cmd, (unsigned long)compat_ptr(arg));
122}
123
124static int w_long(unsigned int fd, unsigned int cmd, unsigned long arg)
125{ 122{
126 mm_segment_t old_fs = get_fs(); 123 mm_segment_t old_fs = get_fs();
127 int err; 124 int err;
128 unsigned long val; 125 unsigned long val;
129 126
130 set_fs (KERNEL_DS); 127 set_fs (KERNEL_DS);
131 err = sys_ioctl(fd, cmd, (unsigned long)&val); 128 err = sys_ioctl(fd, cmd, (unsigned long)&val);
132 set_fs (old_fs); 129 set_fs (old_fs);
133 if (!err && put_user(val, (u32 __user *)compat_ptr(arg))) 130 if (!err && put_user(val, argp))
134 return -EFAULT; 131 return -EFAULT;
135 return err; 132 return err;
136} 133}
137 134
138static int rw_long(unsigned int fd, unsigned int cmd, unsigned long arg) 135static int rw_long(unsigned int fd, unsigned int cmd,
136 compat_ulong_t __user *argp)
139{ 137{
140 mm_segment_t old_fs = get_fs(); 138 mm_segment_t old_fs = get_fs();
141 u32 __user *argptr = compat_ptr(arg);
142 int err; 139 int err;
143 unsigned long val; 140 unsigned long val;
144 141
145 if(get_user(val, argptr)) 142 if(get_user(val, argp))
146 return -EFAULT; 143 return -EFAULT;
147 set_fs (KERNEL_DS); 144 set_fs (KERNEL_DS);
148 err = sys_ioctl(fd, cmd, (unsigned long)&val); 145 err = sys_ioctl(fd, cmd, (unsigned long)&val);
149 set_fs (old_fs); 146 set_fs (old_fs);
150 if (!err && put_user(val, argptr)) 147 if (!err && put_user(val, argp))
151 return -EFAULT; 148 return -EFAULT;
152 return err; 149 return err;
153} 150}
@@ -161,7 +158,8 @@ struct compat_video_event {
161 } u; 158 } u;
162}; 159};
163 160
164static int do_video_get_event(unsigned int fd, unsigned int cmd, unsigned long arg) 161static int do_video_get_event(unsigned int fd, unsigned int cmd,
162 struct compat_video_event __user *up)
165{ 163{
166 struct video_event kevent; 164 struct video_event kevent;
167 mm_segment_t old_fs = get_fs(); 165 mm_segment_t old_fs = get_fs();
@@ -172,8 +170,6 @@ static int do_video_get_event(unsigned int fd, unsigned int cmd, unsigned long a
172 set_fs(old_fs); 170 set_fs(old_fs);
173 171
174 if (!err) { 172 if (!err) {
175 struct compat_video_event __user *up = compat_ptr(arg);
176
177 err = put_user(kevent.type, &up->type); 173 err = put_user(kevent.type, &up->type);
178 err |= put_user(kevent.timestamp, &up->timestamp); 174 err |= put_user(kevent.timestamp, &up->timestamp);
179 err |= put_user(kevent.u.size.w, &up->u.size.w); 175 err |= put_user(kevent.u.size.w, &up->u.size.w);
@@ -192,15 +188,14 @@ struct compat_video_still_picture {
192 int32_t size; 188 int32_t size;
193}; 189};
194 190
195static int do_video_stillpicture(unsigned int fd, unsigned int cmd, unsigned long arg) 191static int do_video_stillpicture(unsigned int fd, unsigned int cmd,
192 struct compat_video_still_picture __user *up)
196{ 193{
197 struct compat_video_still_picture __user *up;
198 struct video_still_picture __user *up_native; 194 struct video_still_picture __user *up_native;
199 compat_uptr_t fp; 195 compat_uptr_t fp;
200 int32_t size; 196 int32_t size;
201 int err; 197 int err;
202 198
203 up = (struct compat_video_still_picture __user *) arg;
204 err = get_user(fp, &up->iFrame); 199 err = get_user(fp, &up->iFrame);
205 err |= get_user(size, &up->size); 200 err |= get_user(size, &up->size);
206 if (err) 201 if (err)
@@ -224,14 +219,13 @@ struct compat_video_spu_palette {
224 compat_uptr_t palette; 219 compat_uptr_t palette;
225}; 220};
226 221
227static int do_video_set_spu_palette(unsigned int fd, unsigned int cmd, unsigned long arg) 222static int do_video_set_spu_palette(unsigned int fd, unsigned int cmd,
223 struct compat_video_spu_palette __user *up)
228{ 224{
229 struct compat_video_spu_palette __user *up;
230 struct video_spu_palette __user *up_native; 225 struct video_spu_palette __user *up_native;
231 compat_uptr_t palp; 226 compat_uptr_t palp;
232 int length, err; 227 int length, err;
233 228
234 up = (struct compat_video_spu_palette __user *) arg;
235 err = get_user(palp, &up->palette); 229 err = get_user(palp, &up->palette);
236 err |= get_user(length, &up->length); 230 err |= get_user(length, &up->length);
237 231
@@ -299,16 +293,15 @@ static int sg_build_iovec(sg_io_hdr_t __user *sgio, void __user *dxferp, u16 iov
299 return 0; 293 return 0;
300} 294}
301 295
302static int sg_ioctl_trans(unsigned int fd, unsigned int cmd, unsigned long arg) 296static int sg_ioctl_trans(unsigned int fd, unsigned int cmd,
297 sg_io_hdr32_t __user *sgio32)
303{ 298{
304 sg_io_hdr_t __user *sgio; 299 sg_io_hdr_t __user *sgio;
305 sg_io_hdr32_t __user *sgio32;
306 u16 iovec_count; 300 u16 iovec_count;
307 u32 data; 301 u32 data;
308 void __user *dxferp; 302 void __user *dxferp;
309 int err; 303 int err;
310 304
311 sgio32 = compat_ptr(arg);
312 if (get_user(iovec_count, &sgio32->iovec_count)) 305 if (get_user(iovec_count, &sgio32->iovec_count))
313 return -EFAULT; 306 return -EFAULT;
314 307
@@ -398,11 +391,11 @@ struct compat_sg_req_info { /* used by SG_GET_REQUEST_TABLE ioctl() */
398 int unused; 391 int unused;
399}; 392};
400 393
401static int sg_grt_trans(unsigned int fd, unsigned int cmd, unsigned long arg) 394static int sg_grt_trans(unsigned int fd, unsigned int cmd, struct
395 compat_sg_req_info __user *o)
402{ 396{
403 int err, i; 397 int err, i;
404 sg_req_info_t __user *r; 398 sg_req_info_t __user *r;
405 struct compat_sg_req_info __user *o = (void __user *)arg;
406 r = compat_alloc_user_space(sizeof(sg_req_info_t)*SG_MAX_QUEUE); 399 r = compat_alloc_user_space(sizeof(sg_req_info_t)*SG_MAX_QUEUE);
407 err = sys_ioctl(fd,cmd,(unsigned long)r); 400 err = sys_ioctl(fd,cmd,(unsigned long)r);
408 if (err < 0) 401 if (err < 0)
@@ -430,9 +423,9 @@ struct sock_fprog32 {
430#define PPPIOCSPASS32 _IOW('t', 71, struct sock_fprog32) 423#define PPPIOCSPASS32 _IOW('t', 71, struct sock_fprog32)
431#define PPPIOCSACTIVE32 _IOW('t', 70, struct sock_fprog32) 424#define PPPIOCSACTIVE32 _IOW('t', 70, struct sock_fprog32)
432 425
433static int ppp_sock_fprog_ioctl_trans(unsigned int fd, unsigned int cmd, unsigned long arg) 426static int ppp_sock_fprog_ioctl_trans(unsigned int fd, unsigned int cmd,
427 struct sock_fprog32 __user *u_fprog32)
434{ 428{
435 struct sock_fprog32 __user *u_fprog32 = compat_ptr(arg);
436 struct sock_fprog __user *u_fprog64 = compat_alloc_user_space(sizeof(struct sock_fprog)); 429 struct sock_fprog __user *u_fprog64 = compat_alloc_user_space(sizeof(struct sock_fprog));
437 void __user *fptr64; 430 void __user *fptr64;
438 u32 fptr32; 431 u32 fptr32;
@@ -469,15 +462,14 @@ struct ppp_idle32 {
469}; 462};
470#define PPPIOCGIDLE32 _IOR('t', 63, struct ppp_idle32) 463#define PPPIOCGIDLE32 _IOR('t', 63, struct ppp_idle32)
471 464
472static int ppp_gidle(unsigned int fd, unsigned int cmd, unsigned long arg) 465static int ppp_gidle(unsigned int fd, unsigned int cmd,
466 struct ppp_idle32 __user *idle32)
473{ 467{
474 struct ppp_idle __user *idle; 468 struct ppp_idle __user *idle;
475 struct ppp_idle32 __user *idle32;
476 __kernel_time_t xmit, recv; 469 __kernel_time_t xmit, recv;
477 int err; 470 int err;
478 471
479 idle = compat_alloc_user_space(sizeof(*idle)); 472 idle = compat_alloc_user_space(sizeof(*idle));
480 idle32 = compat_ptr(arg);
481 473
482 err = sys_ioctl(fd, PPPIOCGIDLE, (unsigned long) idle); 474 err = sys_ioctl(fd, PPPIOCGIDLE, (unsigned long) idle);
483 475
@@ -491,15 +483,14 @@ static int ppp_gidle(unsigned int fd, unsigned int cmd, unsigned long arg)
491 return err; 483 return err;
492} 484}
493 485
494static int ppp_scompress(unsigned int fd, unsigned int cmd, unsigned long arg) 486static int ppp_scompress(unsigned int fd, unsigned int cmd,
487 struct ppp_option_data32 __user *odata32)
495{ 488{
496 struct ppp_option_data __user *odata; 489 struct ppp_option_data __user *odata;
497 struct ppp_option_data32 __user *odata32;
498 __u32 data; 490 __u32 data;
499 void __user *datap; 491 void __user *datap;
500 492
501 odata = compat_alloc_user_space(sizeof(*odata)); 493 odata = compat_alloc_user_space(sizeof(*odata));
502 odata32 = compat_ptr(arg);
503 494
504 if (get_user(data, &odata32->ptr)) 495 if (get_user(data, &odata32->ptr))
505 return -EFAULT; 496 return -EFAULT;
@@ -515,35 +506,6 @@ static int ppp_scompress(unsigned int fd, unsigned int cmd, unsigned long arg)
515 return sys_ioctl(fd, PPPIOCSCOMPRESS, (unsigned long) odata); 506 return sys_ioctl(fd, PPPIOCSCOMPRESS, (unsigned long) odata);
516} 507}
517 508
518static int ppp_ioctl_trans(unsigned int fd, unsigned int cmd, unsigned long arg)
519{
520 int err;
521
522 switch (cmd) {
523 case PPPIOCGIDLE32:
524 err = ppp_gidle(fd, cmd, arg);
525 break;
526
527 case PPPIOCSCOMPRESS32:
528 err = ppp_scompress(fd, cmd, arg);
529 break;
530
531 default:
532 do {
533 static int count;
534 if (++count <= 20)
535 printk("ppp_ioctl: Unknown cmd fd(%d) "
536 "cmd(%08x) arg(%08x)\n",
537 (int)fd, (unsigned int)cmd, (unsigned int)arg);
538 } while(0);
539 err = -EINVAL;
540 break;
541 };
542
543 return err;
544}
545
546
547#ifdef CONFIG_BLOCK 509#ifdef CONFIG_BLOCK
548struct mtget32 { 510struct mtget32 {
549 compat_long_t mt_type; 511 compat_long_t mt_type;
@@ -561,7 +523,7 @@ struct mtpos32 {
561}; 523};
562#define MTIOCPOS32 _IOR('m', 3, struct mtpos32) 524#define MTIOCPOS32 _IOR('m', 3, struct mtpos32)
563 525
564static int mt_ioctl_trans(unsigned int fd, unsigned int cmd, unsigned long arg) 526static int mt_ioctl_trans(unsigned int fd, unsigned int cmd, void __user *argp)
565{ 527{
566 mm_segment_t old_fs = get_fs(); 528 mm_segment_t old_fs = get_fs();
567 struct mtget get; 529 struct mtget get;
@@ -581,15 +543,6 @@ static int mt_ioctl_trans(unsigned int fd, unsigned int cmd, unsigned long arg)
581 kcmd = MTIOCGET; 543 kcmd = MTIOCGET;
582 karg = &get; 544 karg = &get;
583 break; 545 break;
584 default:
585 do {
586 static int count;
587 if (++count <= 20)
588 printk("mt_ioctl: Unknown cmd fd(%d) "
589 "cmd(%08x) arg(%08x)\n",
590 (int)fd, (unsigned int)cmd, (unsigned int)arg);
591 } while(0);
592 return -EINVAL;
593 } 546 }
594 set_fs (KERNEL_DS); 547 set_fs (KERNEL_DS);
595 err = sys_ioctl (fd, kcmd, (unsigned long)karg); 548 err = sys_ioctl (fd, kcmd, (unsigned long)karg);
@@ -598,11 +551,11 @@ static int mt_ioctl_trans(unsigned int fd, unsigned int cmd, unsigned long arg)
598 return err; 551 return err;
599 switch (cmd) { 552 switch (cmd) {
600 case MTIOCPOS32: 553 case MTIOCPOS32:
601 upos32 = compat_ptr(arg); 554 upos32 = argp;
602 err = __put_user(pos.mt_blkno, &upos32->mt_blkno); 555 err = __put_user(pos.mt_blkno, &upos32->mt_blkno);
603 break; 556 break;
604 case MTIOCGET32: 557 case MTIOCGET32:
605 umget32 = compat_ptr(arg); 558 umget32 = argp;
606 err = __put_user(get.mt_type, &umget32->mt_type); 559 err = __put_user(get.mt_type, &umget32->mt_type);
607 err |= __put_user(get.mt_resid, &umget32->mt_resid); 560 err |= __put_user(get.mt_resid, &umget32->mt_resid);
608 err |= __put_user(get.mt_dsreg, &umget32->mt_dsreg); 561 err |= __put_user(get.mt_dsreg, &umget32->mt_dsreg);
@@ -617,162 +570,8 @@ static int mt_ioctl_trans(unsigned int fd, unsigned int cmd, unsigned long arg)
617 570
618#endif /* CONFIG_BLOCK */ 571#endif /* CONFIG_BLOCK */
619 572
620#ifdef CONFIG_VT 573static int do_smb_getmountuid(unsigned int fd, unsigned int cmd,
621 574 compat_uid_t __user *argp)
622static int vt_check(struct file *file)
623{
624 struct tty_struct *tty;
625 struct inode *inode = file->f_path.dentry->d_inode;
626 struct vc_data *vc;
627
628 if (file->f_op->unlocked_ioctl != tty_ioctl)
629 return -EINVAL;
630
631 tty = (struct tty_struct *)file->private_data;
632 if (tty_paranoia_check(tty, inode, "tty_ioctl"))
633 return -EINVAL;
634
635 if (tty->ops->ioctl != vt_ioctl)
636 return -EINVAL;
637
638 vc = (struct vc_data *)tty->driver_data;
639 if (!vc_cons_allocated(vc->vc_num)) /* impossible? */
640 return -ENOIOCTLCMD;
641
642 /*
643 * To have permissions to do most of the vt ioctls, we either have
644 * to be the owner of the tty, or have CAP_SYS_TTY_CONFIG.
645 */
646 if (current->signal->tty == tty || capable(CAP_SYS_TTY_CONFIG))
647 return 1;
648 return 0;
649}
650
651struct consolefontdesc32 {
652 unsigned short charcount; /* characters in font (256 or 512) */
653 unsigned short charheight; /* scan lines per character (1-32) */
654 compat_caddr_t chardata; /* font data in expanded form */
655};
656
657static int do_fontx_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg, struct file *file)
658{
659 struct consolefontdesc32 __user *user_cfd = compat_ptr(arg);
660 struct console_font_op op;
661 compat_caddr_t data;
662 int i, perm;
663
664 perm = vt_check(file);
665 if (perm < 0) return perm;
666
667 switch (cmd) {
668 case PIO_FONTX:
669 if (!perm)
670 return -EPERM;
671 op.op = KD_FONT_OP_SET;
672 op.flags = 0;
673 op.width = 8;
674 if (get_user(op.height, &user_cfd->charheight) ||
675 get_user(op.charcount, &user_cfd->charcount) ||
676 get_user(data, &user_cfd->chardata))
677 return -EFAULT;
678 op.data = compat_ptr(data);
679 return con_font_op(vc_cons[fg_console].d, &op);
680 case GIO_FONTX:
681 op.op = KD_FONT_OP_GET;
682 op.flags = 0;
683 op.width = 8;
684 if (get_user(op.height, &user_cfd->charheight) ||
685 get_user(op.charcount, &user_cfd->charcount) ||
686 get_user(data, &user_cfd->chardata))
687 return -EFAULT;
688 if (!data)
689 return 0;
690 op.data = compat_ptr(data);
691 i = con_font_op(vc_cons[fg_console].d, &op);
692 if (i)
693 return i;
694 if (put_user(op.height, &user_cfd->charheight) ||
695 put_user(op.charcount, &user_cfd->charcount) ||
696 put_user((compat_caddr_t)(unsigned long)op.data,
697 &user_cfd->chardata))
698 return -EFAULT;
699 return 0;
700 }
701 return -EINVAL;
702}
703
704struct console_font_op32 {
705 compat_uint_t op; /* operation code KD_FONT_OP_* */
706 compat_uint_t flags; /* KD_FONT_FLAG_* */
707 compat_uint_t width, height; /* font size */
708 compat_uint_t charcount;
709 compat_caddr_t data; /* font data with height fixed to 32 */
710};
711
712static int do_kdfontop_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg, struct file *file)
713{
714 struct console_font_op op;
715 struct console_font_op32 __user *fontop = compat_ptr(arg);
716 int perm = vt_check(file), i;
717 struct vc_data *vc;
718
719 if (perm < 0) return perm;
720
721 if (copy_from_user(&op, fontop, sizeof(struct console_font_op32)))
722 return -EFAULT;
723 if (!perm && op.op != KD_FONT_OP_GET)
724 return -EPERM;
725 op.data = compat_ptr(((struct console_font_op32 *)&op)->data);
726 op.flags |= KD_FONT_FLAG_OLD;
727 vc = ((struct tty_struct *)file->private_data)->driver_data;
728 i = con_font_op(vc, &op);
729 if (i)
730 return i;
731 ((struct console_font_op32 *)&op)->data = (unsigned long)op.data;
732 if (copy_to_user(fontop, &op, sizeof(struct console_font_op32)))
733 return -EFAULT;
734 return 0;
735}
736
737struct unimapdesc32 {
738 unsigned short entry_ct;
739 compat_caddr_t entries;
740};
741
742static int do_unimap_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg, struct file *file)
743{
744 struct unimapdesc32 tmp;
745 struct unimapdesc32 __user *user_ud = compat_ptr(arg);
746 int perm = vt_check(file);
747 struct vc_data *vc;
748
749 if (perm < 0)
750 return perm;
751 if (copy_from_user(&tmp, user_ud, sizeof tmp))
752 return -EFAULT;
753 if (tmp.entries)
754 if (!access_ok(VERIFY_WRITE, compat_ptr(tmp.entries),
755 tmp.entry_ct*sizeof(struct unipair)))
756 return -EFAULT;
757 vc = ((struct tty_struct *)file->private_data)->driver_data;
758 switch (cmd) {
759 case PIO_UNIMAP:
760 if (!perm)
761 return -EPERM;
762 return con_set_unimap(vc, tmp.entry_ct,
763 compat_ptr(tmp.entries));
764 case GIO_UNIMAP:
765 if (!perm && fg_console != vc->vc_num)
766 return -EPERM;
767 return con_get_unimap(vc, tmp.entry_ct, &(user_ud->entry_ct),
768 compat_ptr(tmp.entries));
769 }
770 return 0;
771}
772
773#endif /* CONFIG_VT */
774
775static int do_smb_getmountuid(unsigned int fd, unsigned int cmd, unsigned long arg)
776{ 575{
777 mm_segment_t old_fs = get_fs(); 576 mm_segment_t old_fs = get_fs();
778 __kernel_uid_t kuid; 577 __kernel_uid_t kuid;
@@ -785,20 +584,15 @@ static int do_smb_getmountuid(unsigned int fd, unsigned int cmd, unsigned long a
785 set_fs(old_fs); 584 set_fs(old_fs);
786 585
787 if (err >= 0) 586 if (err >= 0)
788 err = put_user(kuid, (compat_uid_t __user *)compat_ptr(arg)); 587 err = put_user(kuid, argp);
789 588
790 return err; 589 return err;
791} 590}
792 591
793static __used int 592static int ioc_settimeout(unsigned int fd, unsigned int cmd,
794ret_einval(unsigned int fd, unsigned int cmd, unsigned long arg) 593 compat_ulong_t __user *argp)
795{
796 return -EINVAL;
797}
798
799static int ioc_settimeout(unsigned int fd, unsigned int cmd, unsigned long arg)
800{ 594{
801 return rw_long(fd, AUTOFS_IOC_SETTIMEOUT, arg); 595 return rw_long(fd, AUTOFS_IOC_SETTIMEOUT, argp);
802} 596}
803 597
804/* Bluetooth ioctls */ 598/* Bluetooth ioctls */
@@ -856,7 +650,8 @@ static int set_raw32_request(struct raw_config_request *req, struct raw32_config
856 return ret ? -EFAULT : 0; 650 return ret ? -EFAULT : 0;
857} 651}
858 652
859static int raw_ioctl(unsigned fd, unsigned cmd, unsigned long arg) 653static int raw_ioctl(unsigned fd, unsigned cmd,
654 struct raw32_config_request __user *user_req)
860{ 655{
861 int ret; 656 int ret;
862 657
@@ -864,7 +659,6 @@ static int raw_ioctl(unsigned fd, unsigned cmd, unsigned long arg)
864 case RAW_SETBIND: 659 case RAW_SETBIND:
865 case RAW_GETBIND: { 660 case RAW_GETBIND: {
866 struct raw_config_request req; 661 struct raw_config_request req;
867 struct raw32_config_request __user *user_req = compat_ptr(arg);
868 mm_segment_t oldfs = get_fs(); 662 mm_segment_t oldfs = get_fs();
869 663
870 if ((ret = get_raw32_request(&req, user_req))) 664 if ((ret = get_raw32_request(&req, user_req)))
@@ -879,9 +673,6 @@ static int raw_ioctl(unsigned fd, unsigned cmd, unsigned long arg)
879 } 673 }
880 break; 674 break;
881 } 675 }
882 default:
883 ret = sys_ioctl(fd, cmd, arg);
884 break;
885 } 676 }
886 return ret; 677 return ret;
887} 678}
@@ -909,11 +700,11 @@ struct serial_struct32 {
909 compat_int_t reserved[1]; 700 compat_int_t reserved[1];
910}; 701};
911 702
912static int serial_struct_ioctl(unsigned fd, unsigned cmd, unsigned long arg) 703static int serial_struct_ioctl(unsigned fd, unsigned cmd,
704 struct serial_struct32 __user *ss32)
913{ 705{
914 typedef struct serial_struct SS; 706 typedef struct serial_struct SS;
915 typedef struct serial_struct32 SS32; 707 typedef struct serial_struct32 SS32;
916 struct serial_struct32 __user *ss32 = compat_ptr(arg);
917 int err; 708 int err;
918 struct serial_struct ss; 709 struct serial_struct ss;
919 mm_segment_t oldseg = get_fs(); 710 mm_segment_t oldseg = get_fs();
@@ -951,96 +742,6 @@ static int serial_struct_ioctl(unsigned fd, unsigned cmd, unsigned long arg)
951 return err; 742 return err;
952} 743}
953 744
954struct usbdevfs_ctrltransfer32 {
955 u8 bRequestType;
956 u8 bRequest;
957 u16 wValue;
958 u16 wIndex;
959 u16 wLength;
960 u32 timeout; /* in milliseconds */
961 compat_caddr_t data;
962};
963
964#define USBDEVFS_CONTROL32 _IOWR('U', 0, struct usbdevfs_ctrltransfer32)
965
966static int do_usbdevfs_control(unsigned int fd, unsigned int cmd, unsigned long arg)
967{
968 struct usbdevfs_ctrltransfer32 __user *p32 = compat_ptr(arg);
969 struct usbdevfs_ctrltransfer __user *p;
970 __u32 udata;
971 p = compat_alloc_user_space(sizeof(*p));
972 if (copy_in_user(p, p32, (sizeof(*p32) - sizeof(compat_caddr_t))) ||
973 get_user(udata, &p32->data) ||
974 put_user(compat_ptr(udata), &p->data))
975 return -EFAULT;
976 return sys_ioctl(fd, USBDEVFS_CONTROL, (unsigned long)p);
977}
978
979
980struct usbdevfs_bulktransfer32 {
981 compat_uint_t ep;
982 compat_uint_t len;
983 compat_uint_t timeout; /* in milliseconds */
984 compat_caddr_t data;
985};
986
987#define USBDEVFS_BULK32 _IOWR('U', 2, struct usbdevfs_bulktransfer32)
988
989static int do_usbdevfs_bulk(unsigned int fd, unsigned int cmd, unsigned long arg)
990{
991 struct usbdevfs_bulktransfer32 __user *p32 = compat_ptr(arg);
992 struct usbdevfs_bulktransfer __user *p;
993 compat_uint_t n;
994 compat_caddr_t addr;
995
996 p = compat_alloc_user_space(sizeof(*p));
997
998 if (get_user(n, &p32->ep) || put_user(n, &p->ep) ||
999 get_user(n, &p32->len) || put_user(n, &p->len) ||
1000 get_user(n, &p32->timeout) || put_user(n, &p->timeout) ||
1001 get_user(addr, &p32->data) || put_user(compat_ptr(addr), &p->data))
1002 return -EFAULT;
1003
1004 return sys_ioctl(fd, USBDEVFS_BULK, (unsigned long)p);
1005}
1006
1007
1008/*
1009 * USBDEVFS_SUBMITURB, USBDEVFS_REAPURB and USBDEVFS_REAPURBNDELAY
1010 * are handled in usbdevfs core. -Christopher Li
1011 */
1012
1013struct usbdevfs_disconnectsignal32 {
1014 compat_int_t signr;
1015 compat_caddr_t context;
1016};
1017
1018#define USBDEVFS_DISCSIGNAL32 _IOR('U', 14, struct usbdevfs_disconnectsignal32)
1019
1020static int do_usbdevfs_discsignal(unsigned int fd, unsigned int cmd, unsigned long arg)
1021{
1022 struct usbdevfs_disconnectsignal kdis;
1023 struct usbdevfs_disconnectsignal32 __user *udis;
1024 mm_segment_t old_fs;
1025 u32 uctx;
1026 int err;
1027
1028 udis = compat_ptr(arg);
1029
1030 if (get_user(kdis.signr, &udis->signr) ||
1031 __get_user(uctx, &udis->context))
1032 return -EFAULT;
1033
1034 kdis.context = compat_ptr(uctx);
1035
1036 old_fs = get_fs();
1037 set_fs(KERNEL_DS);
1038 err = sys_ioctl(fd, USBDEVFS_DISCSIGNAL, (unsigned long) &kdis);
1039 set_fs(old_fs);
1040
1041 return err;
1042}
1043
1044/* 745/*
1045 * I2C layer ioctls 746 * I2C layer ioctls
1046 */ 747 */
@@ -1069,9 +770,9 @@ struct i2c_rdwr_aligned {
1069 struct i2c_msg msgs[0]; 770 struct i2c_msg msgs[0];
1070}; 771};
1071 772
1072static int do_i2c_rdwr_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg) 773static int do_i2c_rdwr_ioctl(unsigned int fd, unsigned int cmd,
774 struct i2c_rdwr_ioctl_data32 __user *udata)
1073{ 775{
1074 struct i2c_rdwr_ioctl_data32 __user *udata = compat_ptr(arg);
1075 struct i2c_rdwr_aligned __user *tdata; 776 struct i2c_rdwr_aligned __user *tdata;
1076 struct i2c_msg __user *tmsgs; 777 struct i2c_msg __user *tmsgs;
1077 struct i2c_msg32 __user *umsgs; 778 struct i2c_msg32 __user *umsgs;
@@ -1105,10 +806,10 @@ static int do_i2c_rdwr_ioctl(unsigned int fd, unsigned int cmd, unsigned long ar
1105 return sys_ioctl(fd, cmd, (unsigned long)tdata); 806 return sys_ioctl(fd, cmd, (unsigned long)tdata);
1106} 807}
1107 808
1108static int do_i2c_smbus_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg) 809static int do_i2c_smbus_ioctl(unsigned int fd, unsigned int cmd,
810 struct i2c_smbus_ioctl_data32 __user *udata)
1109{ 811{
1110 struct i2c_smbus_ioctl_data __user *tdata; 812 struct i2c_smbus_ioctl_data __user *tdata;
1111 struct i2c_smbus_ioctl_data32 __user *udata;
1112 compat_caddr_t datap; 813 compat_caddr_t datap;
1113 814
1114 tdata = compat_alloc_user_space(sizeof(*tdata)); 815 tdata = compat_alloc_user_space(sizeof(*tdata));
@@ -1117,7 +818,6 @@ static int do_i2c_smbus_ioctl(unsigned int fd, unsigned int cmd, unsigned long a
1117 if (!access_ok(VERIFY_WRITE, tdata, sizeof(*tdata))) 818 if (!access_ok(VERIFY_WRITE, tdata, sizeof(*tdata)))
1118 return -EFAULT; 819 return -EFAULT;
1119 820
1120 udata = compat_ptr(arg);
1121 if (!access_ok(VERIFY_READ, udata, sizeof(*udata))) 821 if (!access_ok(VERIFY_READ, udata, sizeof(*udata)))
1122 return -EFAULT; 822 return -EFAULT;
1123 823
@@ -1137,7 +837,7 @@ static int do_i2c_smbus_ioctl(unsigned int fd, unsigned int cmd, unsigned long a
1137#define RTC_EPOCH_READ32 _IOR('p', 0x0d, compat_ulong_t) 837#define RTC_EPOCH_READ32 _IOR('p', 0x0d, compat_ulong_t)
1138#define RTC_EPOCH_SET32 _IOW('p', 0x0e, compat_ulong_t) 838#define RTC_EPOCH_SET32 _IOW('p', 0x0e, compat_ulong_t)
1139 839
1140static int rtc_ioctl(unsigned fd, unsigned cmd, unsigned long arg) 840static int rtc_ioctl(unsigned fd, unsigned cmd, void __user *argp)
1141{ 841{
1142 mm_segment_t oldfs = get_fs(); 842 mm_segment_t oldfs = get_fs();
1143 compat_ulong_t val32; 843 compat_ulong_t val32;
@@ -1155,29 +855,14 @@ static int rtc_ioctl(unsigned fd, unsigned cmd, unsigned long arg)
1155 if (ret) 855 if (ret)
1156 return ret; 856 return ret;
1157 val32 = kval; 857 val32 = kval;
1158 return put_user(val32, (unsigned int __user *)arg); 858 return put_user(val32, (unsigned int __user *)argp);
1159 case RTC_IRQP_SET32: 859 case RTC_IRQP_SET32:
1160 return sys_ioctl(fd, RTC_IRQP_SET, arg); 860 return sys_ioctl(fd, RTC_IRQP_SET, (unsigned long)argp);
1161 case RTC_EPOCH_SET32: 861 case RTC_EPOCH_SET32:
1162 return sys_ioctl(fd, RTC_EPOCH_SET, arg); 862 return sys_ioctl(fd, RTC_EPOCH_SET, (unsigned long)argp);
1163 default:
1164 /* unreached */
1165 return -ENOIOCTLCMD;
1166 } 863 }
1167}
1168 864
1169static int 865 return -ENOIOCTLCMD;
1170lp_timeout_trans(unsigned int fd, unsigned int cmd, unsigned long arg)
1171{
1172 struct compat_timeval __user *tc = (struct compat_timeval __user *)arg;
1173 struct timeval __user *tn = compat_alloc_user_space(sizeof(struct timeval));
1174 struct timeval ts;
1175 if (get_user(ts.tv_sec, &tc->tv_sec) ||
1176 get_user(ts.tv_usec, &tc->tv_usec) ||
1177 put_user(ts.tv_sec, &tn->tv_sec) ||
1178 put_user(ts.tv_usec, &tn->tv_usec))
1179 return -EFAULT;
1180 return sys_ioctl(fd, cmd, (unsigned long)tn);
1181} 866}
1182 867
1183/* on ia32 l_start is on a 32-bit boundary */ 868/* on ia32 l_start is on a 32-bit boundary */
@@ -1197,9 +882,9 @@ struct space_resv_32 {
1197#define FS_IOC_RESVSP64_32 _IOW ('X', 42, struct space_resv_32) 882#define FS_IOC_RESVSP64_32 _IOW ('X', 42, struct space_resv_32)
1198 883
1199/* just account for different alignment */ 884/* just account for different alignment */
1200static int compat_ioctl_preallocate(struct file *file, unsigned long arg) 885static int compat_ioctl_preallocate(struct file *file,
886 struct space_resv_32 __user *p32)
1201{ 887{
1202 struct space_resv_32 __user *p32 = compat_ptr(arg);
1203 struct space_resv __user *p = compat_alloc_user_space(sizeof(*p)); 888 struct space_resv __user *p = compat_alloc_user_space(sizeof(*p));
1204 889
1205 if (copy_in_user(&p->l_type, &p32->l_type, sizeof(s16)) || 890 if (copy_in_user(&p->l_type, &p32->l_type, sizeof(s16)) ||
@@ -1215,27 +900,13 @@ static int compat_ioctl_preallocate(struct file *file, unsigned long arg)
1215} 900}
1216#endif 901#endif
1217 902
903/*
904 * simple reversible transform to make our table more evenly
905 * distributed after sorting.
906 */
907#define XFORM(i) (((i) ^ ((i) << 27) ^ ((i) << 17)) & 0xffffffff)
1218 908
1219typedef int (*ioctl_trans_handler_t)(unsigned int, unsigned int, 909#define COMPATIBLE_IOCTL(cmd) XFORM(cmd),
1220 unsigned long, struct file *);
1221
1222struct ioctl_trans {
1223 unsigned long cmd;
1224 ioctl_trans_handler_t handler;
1225 struct ioctl_trans *next;
1226};
1227
1228#define HANDLE_IOCTL(cmd,handler) \
1229 { (cmd), (ioctl_trans_handler_t)(handler) },
1230
1231/* pointer to compatible structure or no argument */
1232#define COMPATIBLE_IOCTL(cmd) \
1233 { (cmd), do_ioctl32_pointer },
1234
1235/* argument is an unsigned long integer, not a pointer */
1236#define ULONG_IOCTL(cmd) \
1237 { (cmd), (ioctl_trans_handler_t)sys_ioctl },
1238
1239/* ioctl should not be warned about even if it's not implemented. 910/* ioctl should not be warned about even if it's not implemented.
1240 Valid reasons to use this: 911 Valid reasons to use this:
1241 - It is implemented with ->compat_ioctl on some device, but programs 912 - It is implemented with ->compat_ioctl on some device, but programs
@@ -1245,7 +916,7 @@ struct ioctl_trans {
1245 Most other reasons are not valid. */ 916 Most other reasons are not valid. */
1246#define IGNORE_IOCTL(cmd) COMPATIBLE_IOCTL(cmd) 917#define IGNORE_IOCTL(cmd) COMPATIBLE_IOCTL(cmd)
1247 918
1248static struct ioctl_trans ioctl_start[] = { 919static unsigned int ioctl_pointer[] = {
1249/* compatible ioctls first */ 920/* compatible ioctls first */
1250COMPATIBLE_IOCTL(0x4B50) /* KDGHWCLK - not in the kernel, but don't complain */ 921COMPATIBLE_IOCTL(0x4B50) /* KDGHWCLK - not in the kernel, but don't complain */
1251COMPATIBLE_IOCTL(0x4B51) /* KDSHWCLK - not in the kernel, but don't complain */ 922COMPATIBLE_IOCTL(0x4B51) /* KDSHWCLK - not in the kernel, but don't complain */
@@ -1256,7 +927,6 @@ COMPATIBLE_IOCTL(TCSETA)
1256COMPATIBLE_IOCTL(TCSETAW) 927COMPATIBLE_IOCTL(TCSETAW)
1257COMPATIBLE_IOCTL(TCSETAF) 928COMPATIBLE_IOCTL(TCSETAF)
1258COMPATIBLE_IOCTL(TCSBRK) 929COMPATIBLE_IOCTL(TCSBRK)
1259ULONG_IOCTL(TCSBRKP)
1260COMPATIBLE_IOCTL(TCXONC) 930COMPATIBLE_IOCTL(TCXONC)
1261COMPATIBLE_IOCTL(TCFLSH) 931COMPATIBLE_IOCTL(TCFLSH)
1262COMPATIBLE_IOCTL(TCGETS) 932COMPATIBLE_IOCTL(TCGETS)
@@ -1266,7 +936,6 @@ COMPATIBLE_IOCTL(TCSETSF)
1266COMPATIBLE_IOCTL(TIOCLINUX) 936COMPATIBLE_IOCTL(TIOCLINUX)
1267COMPATIBLE_IOCTL(TIOCSBRK) 937COMPATIBLE_IOCTL(TIOCSBRK)
1268COMPATIBLE_IOCTL(TIOCCBRK) 938COMPATIBLE_IOCTL(TIOCCBRK)
1269ULONG_IOCTL(TIOCMIWAIT)
1270COMPATIBLE_IOCTL(TIOCGICOUNT) 939COMPATIBLE_IOCTL(TIOCGICOUNT)
1271/* Little t */ 940/* Little t */
1272COMPATIBLE_IOCTL(TIOCGETD) 941COMPATIBLE_IOCTL(TIOCGETD)
@@ -1288,7 +957,6 @@ COMPATIBLE_IOCTL(TIOCSTI)
1288COMPATIBLE_IOCTL(TIOCOUTQ) 957COMPATIBLE_IOCTL(TIOCOUTQ)
1289COMPATIBLE_IOCTL(TIOCSPGRP) 958COMPATIBLE_IOCTL(TIOCSPGRP)
1290COMPATIBLE_IOCTL(TIOCGPGRP) 959COMPATIBLE_IOCTL(TIOCGPGRP)
1291ULONG_IOCTL(TIOCSCTTY)
1292COMPATIBLE_IOCTL(TIOCGPTN) 960COMPATIBLE_IOCTL(TIOCGPTN)
1293COMPATIBLE_IOCTL(TIOCSPTLCK) 961COMPATIBLE_IOCTL(TIOCSPTLCK)
1294COMPATIBLE_IOCTL(TIOCSERGETLSR) 962COMPATIBLE_IOCTL(TIOCSERGETLSR)
@@ -1319,36 +987,21 @@ COMPATIBLE_IOCTL(PRINT_RAID_DEBUG)
1319COMPATIBLE_IOCTL(RAID_AUTORUN) 987COMPATIBLE_IOCTL(RAID_AUTORUN)
1320COMPATIBLE_IOCTL(CLEAR_ARRAY) 988COMPATIBLE_IOCTL(CLEAR_ARRAY)
1321COMPATIBLE_IOCTL(ADD_NEW_DISK) 989COMPATIBLE_IOCTL(ADD_NEW_DISK)
1322ULONG_IOCTL(HOT_REMOVE_DISK)
1323COMPATIBLE_IOCTL(SET_ARRAY_INFO) 990COMPATIBLE_IOCTL(SET_ARRAY_INFO)
1324COMPATIBLE_IOCTL(SET_DISK_INFO) 991COMPATIBLE_IOCTL(SET_DISK_INFO)
1325COMPATIBLE_IOCTL(WRITE_RAID_INFO) 992COMPATIBLE_IOCTL(WRITE_RAID_INFO)
1326COMPATIBLE_IOCTL(UNPROTECT_ARRAY) 993COMPATIBLE_IOCTL(UNPROTECT_ARRAY)
1327COMPATIBLE_IOCTL(PROTECT_ARRAY) 994COMPATIBLE_IOCTL(PROTECT_ARRAY)
1328ULONG_IOCTL(HOT_ADD_DISK)
1329ULONG_IOCTL(SET_DISK_FAULTY)
1330COMPATIBLE_IOCTL(RUN_ARRAY) 995COMPATIBLE_IOCTL(RUN_ARRAY)
1331COMPATIBLE_IOCTL(STOP_ARRAY) 996COMPATIBLE_IOCTL(STOP_ARRAY)
1332COMPATIBLE_IOCTL(STOP_ARRAY_RO) 997COMPATIBLE_IOCTL(STOP_ARRAY_RO)
1333COMPATIBLE_IOCTL(RESTART_ARRAY_RW) 998COMPATIBLE_IOCTL(RESTART_ARRAY_RW)
1334COMPATIBLE_IOCTL(GET_BITMAP_FILE) 999COMPATIBLE_IOCTL(GET_BITMAP_FILE)
1335ULONG_IOCTL(SET_BITMAP_FILE)
1336/* Big K */
1337COMPATIBLE_IOCTL(PIO_FONT)
1338COMPATIBLE_IOCTL(GIO_FONT)
1339COMPATIBLE_IOCTL(PIO_CMAP)
1340COMPATIBLE_IOCTL(GIO_CMAP)
1341ULONG_IOCTL(KDSIGACCEPT)
1342COMPATIBLE_IOCTL(KDGETKEYCODE) 1000COMPATIBLE_IOCTL(KDGETKEYCODE)
1343COMPATIBLE_IOCTL(KDSETKEYCODE) 1001COMPATIBLE_IOCTL(KDSETKEYCODE)
1344ULONG_IOCTL(KIOCSOUND)
1345ULONG_IOCTL(KDMKTONE)
1346COMPATIBLE_IOCTL(KDGKBTYPE) 1002COMPATIBLE_IOCTL(KDGKBTYPE)
1347ULONG_IOCTL(KDSETMODE)
1348COMPATIBLE_IOCTL(KDGETMODE) 1003COMPATIBLE_IOCTL(KDGETMODE)
1349ULONG_IOCTL(KDSKBMODE)
1350COMPATIBLE_IOCTL(KDGKBMODE) 1004COMPATIBLE_IOCTL(KDGKBMODE)
1351ULONG_IOCTL(KDSKBMETA)
1352COMPATIBLE_IOCTL(KDGKBMETA) 1005COMPATIBLE_IOCTL(KDGKBMETA)
1353COMPATIBLE_IOCTL(KDGKBENT) 1006COMPATIBLE_IOCTL(KDGKBENT)
1354COMPATIBLE_IOCTL(KDSKBENT) 1007COMPATIBLE_IOCTL(KDSKBENT)
@@ -1358,15 +1011,7 @@ COMPATIBLE_IOCTL(KDGKBDIACR)
1358COMPATIBLE_IOCTL(KDSKBDIACR) 1011COMPATIBLE_IOCTL(KDSKBDIACR)
1359COMPATIBLE_IOCTL(KDKBDREP) 1012COMPATIBLE_IOCTL(KDKBDREP)
1360COMPATIBLE_IOCTL(KDGKBLED) 1013COMPATIBLE_IOCTL(KDGKBLED)
1361ULONG_IOCTL(KDSKBLED)
1362COMPATIBLE_IOCTL(KDGETLED) 1014COMPATIBLE_IOCTL(KDGETLED)
1363ULONG_IOCTL(KDSETLED)
1364COMPATIBLE_IOCTL(GIO_SCRNMAP)
1365COMPATIBLE_IOCTL(PIO_SCRNMAP)
1366COMPATIBLE_IOCTL(GIO_UNISCRNMAP)
1367COMPATIBLE_IOCTL(PIO_UNISCRNMAP)
1368COMPATIBLE_IOCTL(PIO_FONTRESET)
1369COMPATIBLE_IOCTL(PIO_UNIMAPCLR)
1370#ifdef CONFIG_BLOCK 1015#ifdef CONFIG_BLOCK
1371/* Big S */ 1016/* Big S */
1372COMPATIBLE_IOCTL(SCSI_IOCTL_GET_IDLUN) 1017COMPATIBLE_IOCTL(SCSI_IOCTL_GET_IDLUN)
@@ -1378,20 +1023,6 @@ COMPATIBLE_IOCTL(SCSI_IOCTL_SEND_COMMAND)
1378COMPATIBLE_IOCTL(SCSI_IOCTL_PROBE_HOST) 1023COMPATIBLE_IOCTL(SCSI_IOCTL_PROBE_HOST)
1379COMPATIBLE_IOCTL(SCSI_IOCTL_GET_PCI) 1024COMPATIBLE_IOCTL(SCSI_IOCTL_GET_PCI)
1380#endif 1025#endif
1381/* Big V */
1382COMPATIBLE_IOCTL(VT_SETMODE)
1383COMPATIBLE_IOCTL(VT_GETMODE)
1384COMPATIBLE_IOCTL(VT_GETSTATE)
1385COMPATIBLE_IOCTL(VT_OPENQRY)
1386ULONG_IOCTL(VT_ACTIVATE)
1387ULONG_IOCTL(VT_WAITACTIVE)
1388ULONG_IOCTL(VT_RELDISP)
1389ULONG_IOCTL(VT_DISALLOCATE)
1390COMPATIBLE_IOCTL(VT_RESIZE)
1391COMPATIBLE_IOCTL(VT_RESIZEX)
1392COMPATIBLE_IOCTL(VT_LOCKSWITCH)
1393COMPATIBLE_IOCTL(VT_UNLOCKSWITCH)
1394COMPATIBLE_IOCTL(VT_GETHIFONTMASK)
1395/* Little p (/dev/rtc, /dev/envctrl, etc.) */ 1026/* Little p (/dev/rtc, /dev/envctrl, etc.) */
1396COMPATIBLE_IOCTL(RTC_AIE_ON) 1027COMPATIBLE_IOCTL(RTC_AIE_ON)
1397COMPATIBLE_IOCTL(RTC_AIE_OFF) 1028COMPATIBLE_IOCTL(RTC_AIE_OFF)
@@ -1420,11 +1051,12 @@ COMPATIBLE_IOCTL(MTIOCTOP)
1420/* Socket level stuff */ 1051/* Socket level stuff */
1421COMPATIBLE_IOCTL(FIOQSIZE) 1052COMPATIBLE_IOCTL(FIOQSIZE)
1422#ifdef CONFIG_BLOCK 1053#ifdef CONFIG_BLOCK
1054/* loop */
1055IGNORE_IOCTL(LOOP_CLR_FD)
1423/* SG stuff */ 1056/* SG stuff */
1424COMPATIBLE_IOCTL(SG_SET_TIMEOUT) 1057COMPATIBLE_IOCTL(SG_SET_TIMEOUT)
1425COMPATIBLE_IOCTL(SG_GET_TIMEOUT) 1058COMPATIBLE_IOCTL(SG_GET_TIMEOUT)
1426COMPATIBLE_IOCTL(SG_EMULATED_HOST) 1059COMPATIBLE_IOCTL(SG_EMULATED_HOST)
1427ULONG_IOCTL(SG_SET_TRANSFORM)
1428COMPATIBLE_IOCTL(SG_GET_TRANSFORM) 1060COMPATIBLE_IOCTL(SG_GET_TRANSFORM)
1429COMPATIBLE_IOCTL(SG_SET_RESERVED_SIZE) 1061COMPATIBLE_IOCTL(SG_SET_RESERVED_SIZE)
1430COMPATIBLE_IOCTL(SG_GET_RESERVED_SIZE) 1062COMPATIBLE_IOCTL(SG_GET_RESERVED_SIZE)
@@ -1478,8 +1110,6 @@ COMPATIBLE_IOCTL(PPPIOCGCHAN)
1478/* PPPOX */ 1110/* PPPOX */
1479COMPATIBLE_IOCTL(PPPOEIOCSFWD) 1111COMPATIBLE_IOCTL(PPPOEIOCSFWD)
1480COMPATIBLE_IOCTL(PPPOEIOCDFWD) 1112COMPATIBLE_IOCTL(PPPOEIOCDFWD)
1481/* LP */
1482COMPATIBLE_IOCTL(LPGETSTATUS)
1483/* ppdev */ 1113/* ppdev */
1484COMPATIBLE_IOCTL(PPSETMODE) 1114COMPATIBLE_IOCTL(PPSETMODE)
1485COMPATIBLE_IOCTL(PPRSTATUS) 1115COMPATIBLE_IOCTL(PPRSTATUS)
@@ -1661,8 +1291,6 @@ COMPATIBLE_IOCTL(SOUND_MIXER_GETLEVELS)
1661COMPATIBLE_IOCTL(SOUND_MIXER_SETLEVELS) 1291COMPATIBLE_IOCTL(SOUND_MIXER_SETLEVELS)
1662COMPATIBLE_IOCTL(OSS_GETVERSION) 1292COMPATIBLE_IOCTL(OSS_GETVERSION)
1663/* AUTOFS */ 1293/* AUTOFS */
1664ULONG_IOCTL(AUTOFS_IOC_READY)
1665ULONG_IOCTL(AUTOFS_IOC_FAIL)
1666COMPATIBLE_IOCTL(AUTOFS_IOC_CATATONIC) 1294COMPATIBLE_IOCTL(AUTOFS_IOC_CATATONIC)
1667COMPATIBLE_IOCTL(AUTOFS_IOC_PROTOVER) 1295COMPATIBLE_IOCTL(AUTOFS_IOC_PROTOVER)
1668COMPATIBLE_IOCTL(AUTOFS_IOC_EXPIRE) 1296COMPATIBLE_IOCTL(AUTOFS_IOC_EXPIRE)
@@ -1755,30 +1383,11 @@ COMPATIBLE_IOCTL(PCIIOC_CONTROLLER)
1755COMPATIBLE_IOCTL(PCIIOC_MMAP_IS_IO) 1383COMPATIBLE_IOCTL(PCIIOC_MMAP_IS_IO)
1756COMPATIBLE_IOCTL(PCIIOC_MMAP_IS_MEM) 1384COMPATIBLE_IOCTL(PCIIOC_MMAP_IS_MEM)
1757COMPATIBLE_IOCTL(PCIIOC_WRITE_COMBINE) 1385COMPATIBLE_IOCTL(PCIIOC_WRITE_COMBINE)
1758/* USB */
1759COMPATIBLE_IOCTL(USBDEVFS_RESETEP)
1760COMPATIBLE_IOCTL(USBDEVFS_SETINTERFACE)
1761COMPATIBLE_IOCTL(USBDEVFS_SETCONFIGURATION)
1762COMPATIBLE_IOCTL(USBDEVFS_GETDRIVER)
1763COMPATIBLE_IOCTL(USBDEVFS_DISCARDURB)
1764COMPATIBLE_IOCTL(USBDEVFS_CLAIMINTERFACE)
1765COMPATIBLE_IOCTL(USBDEVFS_RELEASEINTERFACE)
1766COMPATIBLE_IOCTL(USBDEVFS_CONNECTINFO)
1767COMPATIBLE_IOCTL(USBDEVFS_HUB_PORTINFO)
1768COMPATIBLE_IOCTL(USBDEVFS_RESET)
1769COMPATIBLE_IOCTL(USBDEVFS_SUBMITURB32)
1770COMPATIBLE_IOCTL(USBDEVFS_REAPURB32)
1771COMPATIBLE_IOCTL(USBDEVFS_REAPURBNDELAY32)
1772COMPATIBLE_IOCTL(USBDEVFS_CLEAR_HALT)
1773/* NBD */ 1386/* NBD */
1774ULONG_IOCTL(NBD_SET_SOCK)
1775ULONG_IOCTL(NBD_SET_BLKSIZE)
1776ULONG_IOCTL(NBD_SET_SIZE)
1777COMPATIBLE_IOCTL(NBD_DO_IT) 1387COMPATIBLE_IOCTL(NBD_DO_IT)
1778COMPATIBLE_IOCTL(NBD_CLEAR_SOCK) 1388COMPATIBLE_IOCTL(NBD_CLEAR_SOCK)
1779COMPATIBLE_IOCTL(NBD_CLEAR_QUE) 1389COMPATIBLE_IOCTL(NBD_CLEAR_QUE)
1780COMPATIBLE_IOCTL(NBD_PRINT_DEBUG) 1390COMPATIBLE_IOCTL(NBD_PRINT_DEBUG)
1781ULONG_IOCTL(NBD_SET_SIZE_BLOCKS)
1782COMPATIBLE_IOCTL(NBD_DISCONNECT) 1391COMPATIBLE_IOCTL(NBD_DISCONNECT)
1783/* i2c */ 1392/* i2c */
1784COMPATIBLE_IOCTL(I2C_SLAVE) 1393COMPATIBLE_IOCTL(I2C_SLAVE)
@@ -1878,42 +1487,6 @@ COMPATIBLE_IOCTL(JSIOCGAXES)
1878COMPATIBLE_IOCTL(JSIOCGBUTTONS) 1487COMPATIBLE_IOCTL(JSIOCGBUTTONS)
1879COMPATIBLE_IOCTL(JSIOCGNAME(0)) 1488COMPATIBLE_IOCTL(JSIOCGNAME(0))
1880 1489
1881/* now things that need handlers */
1882#ifdef CONFIG_BLOCK
1883HANDLE_IOCTL(SG_IO,sg_ioctl_trans)
1884HANDLE_IOCTL(SG_GET_REQUEST_TABLE, sg_grt_trans)
1885#endif
1886HANDLE_IOCTL(PPPIOCGIDLE32, ppp_ioctl_trans)
1887HANDLE_IOCTL(PPPIOCSCOMPRESS32, ppp_ioctl_trans)
1888HANDLE_IOCTL(PPPIOCSPASS32, ppp_sock_fprog_ioctl_trans)
1889HANDLE_IOCTL(PPPIOCSACTIVE32, ppp_sock_fprog_ioctl_trans)
1890#ifdef CONFIG_BLOCK
1891HANDLE_IOCTL(MTIOCGET32, mt_ioctl_trans)
1892HANDLE_IOCTL(MTIOCPOS32, mt_ioctl_trans)
1893#endif
1894#define AUTOFS_IOC_SETTIMEOUT32 _IOWR(0x93,0x64,unsigned int)
1895HANDLE_IOCTL(AUTOFS_IOC_SETTIMEOUT32, ioc_settimeout)
1896#ifdef CONFIG_VT
1897HANDLE_IOCTL(PIO_FONTX, do_fontx_ioctl)
1898HANDLE_IOCTL(GIO_FONTX, do_fontx_ioctl)
1899HANDLE_IOCTL(PIO_UNIMAP, do_unimap_ioctl)
1900HANDLE_IOCTL(GIO_UNIMAP, do_unimap_ioctl)
1901HANDLE_IOCTL(KDFONTOP, do_kdfontop_ioctl)
1902#endif
1903/* One SMB ioctl needs translations. */
1904#define SMB_IOC_GETMOUNTUID_32 _IOR('u', 1, compat_uid_t)
1905HANDLE_IOCTL(SMB_IOC_GETMOUNTUID_32, do_smb_getmountuid)
1906/* block stuff */
1907#ifdef CONFIG_BLOCK
1908/* loop */
1909IGNORE_IOCTL(LOOP_CLR_FD)
1910/* Raw devices */
1911HANDLE_IOCTL(RAW_SETBIND, raw_ioctl)
1912HANDLE_IOCTL(RAW_GETBIND, raw_ioctl)
1913#endif
1914/* Serial */
1915HANDLE_IOCTL(TIOCGSERIAL, serial_struct_ioctl)
1916HANDLE_IOCTL(TIOCSSERIAL, serial_struct_ioctl)
1917#ifdef TIOCGLTC 1490#ifdef TIOCGLTC
1918COMPATIBLE_IOCTL(TIOCGLTC) 1491COMPATIBLE_IOCTL(TIOCGLTC)
1919COMPATIBLE_IOCTL(TIOCSLTC) 1492COMPATIBLE_IOCTL(TIOCSLTC)
@@ -1928,39 +1501,6 @@ COMPATIBLE_IOCTL(TIOCSLTC)
1928COMPATIBLE_IOCTL(TIOCSTART) 1501COMPATIBLE_IOCTL(TIOCSTART)
1929COMPATIBLE_IOCTL(TIOCSTOP) 1502COMPATIBLE_IOCTL(TIOCSTOP)
1930#endif 1503#endif
1931/* Usbdevfs */
1932HANDLE_IOCTL(USBDEVFS_CONTROL32, do_usbdevfs_control)
1933HANDLE_IOCTL(USBDEVFS_BULK32, do_usbdevfs_bulk)
1934HANDLE_IOCTL(USBDEVFS_DISCSIGNAL32, do_usbdevfs_discsignal)
1935COMPATIBLE_IOCTL(USBDEVFS_IOCTL32)
1936/* i2c */
1937HANDLE_IOCTL(I2C_FUNCS, w_long)
1938HANDLE_IOCTL(I2C_RDWR, do_i2c_rdwr_ioctl)
1939HANDLE_IOCTL(I2C_SMBUS, do_i2c_smbus_ioctl)
1940/* Not implemented in the native kernel */
1941HANDLE_IOCTL(RTC_IRQP_READ32, rtc_ioctl)
1942HANDLE_IOCTL(RTC_IRQP_SET32, rtc_ioctl)
1943HANDLE_IOCTL(RTC_EPOCH_READ32, rtc_ioctl)
1944HANDLE_IOCTL(RTC_EPOCH_SET32, rtc_ioctl)
1945
1946/* dvb */
1947HANDLE_IOCTL(VIDEO_GET_EVENT, do_video_get_event)
1948HANDLE_IOCTL(VIDEO_STILLPICTURE, do_video_stillpicture)
1949HANDLE_IOCTL(VIDEO_SET_SPU_PALETTE, do_video_set_spu_palette)
1950
1951/* parport */
1952COMPATIBLE_IOCTL(LPTIME)
1953COMPATIBLE_IOCTL(LPCHAR)
1954COMPATIBLE_IOCTL(LPABORTOPEN)
1955COMPATIBLE_IOCTL(LPCAREFUL)
1956COMPATIBLE_IOCTL(LPWAIT)
1957COMPATIBLE_IOCTL(LPSETIRQ)
1958COMPATIBLE_IOCTL(LPGETSTATUS)
1959COMPATIBLE_IOCTL(LPGETSTATUS)
1960COMPATIBLE_IOCTL(LPRESET)
1961/*LPGETSTATS not implemented, but no kernels seem to compile it in anyways*/
1962COMPATIBLE_IOCTL(LPGETFLAGS)
1963HANDLE_IOCTL(LPSETTIMEOUT, lp_timeout_trans)
1964 1504
1965/* fat 'r' ioctls. These are handled by fat with ->compat_ioctl, 1505/* fat 'r' ioctls. These are handled by fat with ->compat_ioctl,
1966 but we don't want warnings on other file systems. So declare 1506 but we don't want warnings on other file systems. So declare
@@ -1988,12 +1528,110 @@ IGNORE_IOCTL(FBIOGCURSOR32)
1988#endif 1528#endif
1989}; 1529};
1990 1530
1991#define IOCTL_HASHSIZE 256 1531/*
1992static struct ioctl_trans *ioctl32_hash_table[IOCTL_HASHSIZE]; 1532 * Convert common ioctl arguments based on their command number
1993 1533 *
1994static inline unsigned long ioctl32_hash(unsigned long cmd) 1534 * Please do not add any code in here. Instead, implement
1535 * a compat_ioctl operation in the place that handleѕ the
1536 * ioctl for the native case.
1537 */
1538static long do_ioctl_trans(int fd, unsigned int cmd,
1539 unsigned long arg, struct file *file)
1995{ 1540{
1996 return (((cmd >> 6) ^ (cmd >> 4) ^ cmd)) % IOCTL_HASHSIZE; 1541 void __user *argp = compat_ptr(arg);
1542
1543 switch (cmd) {
1544 case PPPIOCGIDLE32:
1545 return ppp_gidle(fd, cmd, argp);
1546 case PPPIOCSCOMPRESS32:
1547 return ppp_scompress(fd, cmd, argp);
1548 case PPPIOCSPASS32:
1549 case PPPIOCSACTIVE32:
1550 return ppp_sock_fprog_ioctl_trans(fd, cmd, argp);
1551#ifdef CONFIG_BLOCK
1552 case SG_IO:
1553 return sg_ioctl_trans(fd, cmd, argp);
1554 case SG_GET_REQUEST_TABLE:
1555 return sg_grt_trans(fd, cmd, argp);
1556 case MTIOCGET32:
1557 case MTIOCPOS32:
1558 return mt_ioctl_trans(fd, cmd, argp);
1559 /* Raw devices */
1560 case RAW_SETBIND:
1561 case RAW_GETBIND:
1562 return raw_ioctl(fd, cmd, argp);
1563#endif
1564#define AUTOFS_IOC_SETTIMEOUT32 _IOWR(0x93,0x64,unsigned int)
1565 case AUTOFS_IOC_SETTIMEOUT32:
1566 return ioc_settimeout(fd, cmd, argp);
1567 /* One SMB ioctl needs translations. */
1568#define SMB_IOC_GETMOUNTUID_32 _IOR('u', 1, compat_uid_t)
1569 case SMB_IOC_GETMOUNTUID_32:
1570 return do_smb_getmountuid(fd, cmd, argp);
1571 /* Serial */
1572 case TIOCGSERIAL:
1573 case TIOCSSERIAL:
1574 return serial_struct_ioctl(fd, cmd, argp);
1575 /* i2c */
1576 case I2C_FUNCS:
1577 return w_long(fd, cmd, argp);
1578 case I2C_RDWR:
1579 return do_i2c_rdwr_ioctl(fd, cmd, argp);
1580 case I2C_SMBUS:
1581 return do_i2c_smbus_ioctl(fd, cmd, argp);
1582 /* Not implemented in the native kernel */
1583 case RTC_IRQP_READ32:
1584 case RTC_IRQP_SET32:
1585 case RTC_EPOCH_READ32:
1586 case RTC_EPOCH_SET32:
1587 return rtc_ioctl(fd, cmd, argp);
1588
1589 /* dvb */
1590 case VIDEO_GET_EVENT:
1591 return do_video_get_event(fd, cmd, argp);
1592 case VIDEO_STILLPICTURE:
1593 return do_video_stillpicture(fd, cmd, argp);
1594 case VIDEO_SET_SPU_PALETTE:
1595 return do_video_set_spu_palette(fd, cmd, argp);
1596 }
1597
1598 /*
1599 * These take an integer instead of a pointer as 'arg',
1600 * so we must not do a compat_ptr() translation.
1601 */
1602 switch (cmd) {
1603 /* Big T */
1604 case TCSBRKP:
1605 case TIOCMIWAIT:
1606 case TIOCSCTTY:
1607 /* RAID */
1608 case HOT_REMOVE_DISK:
1609 case HOT_ADD_DISK:
1610 case SET_DISK_FAULTY:
1611 case SET_BITMAP_FILE:
1612 /* Big K */
1613 case KDSIGACCEPT:
1614 case KIOCSOUND:
1615 case KDMKTONE:
1616 case KDSETMODE:
1617 case KDSKBMODE:
1618 case KDSKBMETA:
1619 case KDSKBLED:
1620 case KDSETLED:
1621 /* SG stuff */
1622 case SG_SET_TRANSFORM:
1623 /* AUTOFS */
1624 case AUTOFS_IOC_READY:
1625 case AUTOFS_IOC_FAIL:
1626 /* NBD */
1627 case NBD_SET_SOCK:
1628 case NBD_SET_BLKSIZE:
1629 case NBD_SET_SIZE:
1630 case NBD_SET_SIZE_BLOCKS:
1631 return do_vfs_ioctl(file, fd, cmd, arg);
1632 }
1633
1634 return -ENOIOCTLCMD;
1997} 1635}
1998 1636
1999static void compat_ioctl_error(struct file *filp, unsigned int fd, 1637static void compat_ioctl_error(struct file *filp, unsigned int fd,
@@ -2025,12 +1663,33 @@ static void compat_ioctl_error(struct file *filp, unsigned int fd,
2025 free_page((unsigned long)path); 1663 free_page((unsigned long)path);
2026} 1664}
2027 1665
1666static int compat_ioctl_check_table(unsigned int xcmd)
1667{
1668 int i;
1669 const int max = ARRAY_SIZE(ioctl_pointer) - 1;
1670
1671 BUILD_BUG_ON(max >= (1 << 16));
1672
1673 /* guess initial offset into table, assuming a
1674 normalized distribution */
1675 i = ((xcmd >> 16) * max) >> 16;
1676
1677 /* do linear search up first, until greater or equal */
1678 while (ioctl_pointer[i] < xcmd && i < max)
1679 i++;
1680
1681 /* then do linear search down */
1682 while (ioctl_pointer[i] > xcmd && i > 0)
1683 i--;
1684
1685 return ioctl_pointer[i] == xcmd;
1686}
1687
2028asmlinkage long compat_sys_ioctl(unsigned int fd, unsigned int cmd, 1688asmlinkage long compat_sys_ioctl(unsigned int fd, unsigned int cmd,
2029 unsigned long arg) 1689 unsigned long arg)
2030{ 1690{
2031 struct file *filp; 1691 struct file *filp;
2032 int error = -EBADF; 1692 int error = -EBADF;
2033 struct ioctl_trans *t;
2034 int fput_needed; 1693 int fput_needed;
2035 1694
2036 filp = fget_light(fd, &fput_needed); 1695 filp = fget_light(fd, &fput_needed);
@@ -2058,7 +1717,7 @@ asmlinkage long compat_sys_ioctl(unsigned int fd, unsigned int cmd,
2058#if defined(CONFIG_IA64) || defined(CONFIG_X86_64) 1717#if defined(CONFIG_IA64) || defined(CONFIG_X86_64)
2059 case FS_IOC_RESVSP_32: 1718 case FS_IOC_RESVSP_32:
2060 case FS_IOC_RESVSP64_32: 1719 case FS_IOC_RESVSP64_32:
2061 error = compat_ioctl_preallocate(filp, arg); 1720 error = compat_ioctl_preallocate(filp, compat_ptr(arg));
2062 goto out_fput; 1721 goto out_fput;
2063#else 1722#else
2064 case FS_IOC_RESVSP: 1723 case FS_IOC_RESVSP:
@@ -2087,12 +1746,11 @@ asmlinkage long compat_sys_ioctl(unsigned int fd, unsigned int cmd,
2087 break; 1746 break;
2088 } 1747 }
2089 1748
2090 for (t = ioctl32_hash_table[ioctl32_hash(cmd)]; t; t = t->next) { 1749 if (compat_ioctl_check_table(XFORM(cmd)))
2091 if (t->cmd == cmd) 1750 goto found_handler;
2092 goto found_handler;
2093 }
2094 1751
2095 { 1752 error = do_ioctl_trans(fd, cmd, arg, filp);
1753 if (error == -ENOIOCTLCMD) {
2096 static int count; 1754 static int count;
2097 1755
2098 if (++count <= 50) 1756 if (++count <= 50)
@@ -2103,13 +1761,7 @@ asmlinkage long compat_sys_ioctl(unsigned int fd, unsigned int cmd,
2103 goto out_fput; 1761 goto out_fput;
2104 1762
2105 found_handler: 1763 found_handler:
2106 if (t->handler) { 1764 arg = (unsigned long)compat_ptr(arg);
2107 lock_kernel();
2108 error = t->handler(fd, cmd, arg, filp);
2109 unlock_kernel();
2110 goto out_fput;
2111 }
2112
2113 do_ioctl: 1765 do_ioctl:
2114 error = do_vfs_ioctl(filp, fd, cmd, arg); 1766 error = do_vfs_ioctl(filp, fd, cmd, arg);
2115 out_fput: 1767 out_fput:
@@ -2118,35 +1770,22 @@ asmlinkage long compat_sys_ioctl(unsigned int fd, unsigned int cmd,
2118 return error; 1770 return error;
2119} 1771}
2120 1772
2121static void ioctl32_insert_translation(struct ioctl_trans *trans) 1773static int __init init_sys32_ioctl_cmp(const void *p, const void *q)
2122{ 1774{
2123 unsigned long hash; 1775 unsigned int a, b;
2124 struct ioctl_trans *t; 1776 a = *(unsigned int *)p;
2125 1777 b = *(unsigned int *)q;
2126 hash = ioctl32_hash (trans->cmd); 1778 if (a > b)
2127 if (!ioctl32_hash_table[hash]) 1779 return 1;
2128 ioctl32_hash_table[hash] = trans; 1780 if (a < b)
2129 else { 1781 return -1;
2130 t = ioctl32_hash_table[hash]; 1782 return 0;
2131 while (t->next)
2132 t = t->next;
2133 trans->next = NULL;
2134 t->next = trans;
2135 }
2136} 1783}
2137 1784
2138static int __init init_sys32_ioctl(void) 1785static int __init init_sys32_ioctl(void)
2139{ 1786{
2140 int i; 1787 sort(ioctl_pointer, ARRAY_SIZE(ioctl_pointer), sizeof(*ioctl_pointer),
2141 1788 init_sys32_ioctl_cmp, NULL);
2142 for (i = 0; i < ARRAY_SIZE(ioctl_start); i++) {
2143 if (ioctl_start[i].next) {
2144 printk("ioctl translation %d bad\n",i);
2145 return -1;
2146 }
2147
2148 ioctl32_insert_translation(&ioctl_start[i]);
2149 }
2150 return 0; 1789 return 0;
2151} 1790}
2152__initcall(init_sys32_ioctl); 1791__initcall(init_sys32_ioctl);