diff options
-rw-r--r-- | drivers/video/fbmem.c | 147 | ||||
-rw-r--r-- | fs/compat_ioctl.c | 143 | ||||
-rw-r--r-- | include/linux/compat_ioctl.h | 7 |
3 files changed, 142 insertions, 155 deletions
diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c index 81b6cd23ea1d..9f180096c896 100644 --- a/drivers/video/fbmem.c +++ b/drivers/video/fbmem.c | |||
@@ -14,6 +14,7 @@ | |||
14 | #include <linux/config.h> | 14 | #include <linux/config.h> |
15 | #include <linux/module.h> | 15 | #include <linux/module.h> |
16 | 16 | ||
17 | #include <linux/compat.h> | ||
17 | #include <linux/types.h> | 18 | #include <linux/types.h> |
18 | #include <linux/errno.h> | 19 | #include <linux/errno.h> |
19 | #include <linux/sched.h> | 20 | #include <linux/sched.h> |
@@ -933,18 +934,154 @@ fb_ioctl(struct inode *inode, struct file *file, unsigned int cmd, | |||
933 | } | 934 | } |
934 | 935 | ||
935 | #ifdef CONFIG_COMPAT | 936 | #ifdef CONFIG_COMPAT |
937 | struct fb_fix_screeninfo32 { | ||
938 | char id[16]; | ||
939 | compat_caddr_t smem_start; | ||
940 | u32 smem_len; | ||
941 | u32 type; | ||
942 | u32 type_aux; | ||
943 | u32 visual; | ||
944 | u16 xpanstep; | ||
945 | u16 ypanstep; | ||
946 | u16 ywrapstep; | ||
947 | u32 line_length; | ||
948 | compat_caddr_t mmio_start; | ||
949 | u32 mmio_len; | ||
950 | u32 accel; | ||
951 | u16 reserved[3]; | ||
952 | }; | ||
953 | |||
954 | struct fb_cmap32 { | ||
955 | u32 start; | ||
956 | u32 len; | ||
957 | compat_caddr_t red; | ||
958 | compat_caddr_t green; | ||
959 | compat_caddr_t blue; | ||
960 | compat_caddr_t transp; | ||
961 | }; | ||
962 | |||
963 | static int fb_getput_cmap(struct inode *inode, struct file *file, | ||
964 | unsigned int cmd, unsigned long arg) | ||
965 | { | ||
966 | struct fb_cmap_user __user *cmap; | ||
967 | struct fb_cmap32 __user *cmap32; | ||
968 | __u32 data; | ||
969 | int err; | ||
970 | |||
971 | cmap = compat_alloc_user_space(sizeof(*cmap)); | ||
972 | cmap32 = compat_ptr(arg); | ||
973 | |||
974 | if (copy_in_user(&cmap->start, &cmap32->start, 2 * sizeof(__u32))) | ||
975 | return -EFAULT; | ||
976 | |||
977 | if (get_user(data, &cmap32->red) || | ||
978 | put_user(compat_ptr(data), &cmap->red) || | ||
979 | get_user(data, &cmap32->green) || | ||
980 | put_user(compat_ptr(data), &cmap->green) || | ||
981 | get_user(data, &cmap32->blue) || | ||
982 | put_user(compat_ptr(data), &cmap->blue) || | ||
983 | get_user(data, &cmap32->transp) || | ||
984 | put_user(compat_ptr(data), &cmap->transp)) | ||
985 | return -EFAULT; | ||
986 | |||
987 | err = fb_ioctl(inode, file, cmd, (unsigned long) cmap); | ||
988 | |||
989 | if (!err) { | ||
990 | if (copy_in_user(&cmap32->start, | ||
991 | &cmap->start, | ||
992 | 2 * sizeof(__u32))) | ||
993 | err = -EFAULT; | ||
994 | } | ||
995 | return err; | ||
996 | } | ||
997 | |||
998 | static int do_fscreeninfo_to_user(struct fb_fix_screeninfo *fix, | ||
999 | struct fb_fix_screeninfo32 __user *fix32) | ||
1000 | { | ||
1001 | __u32 data; | ||
1002 | int err; | ||
1003 | |||
1004 | err = copy_to_user(&fix32->id, &fix->id, sizeof(fix32->id)); | ||
1005 | |||
1006 | data = (__u32) (unsigned long) fix->smem_start; | ||
1007 | err |= put_user(data, &fix32->smem_start); | ||
1008 | |||
1009 | err |= put_user(fix->smem_len, &fix32->smem_len); | ||
1010 | err |= put_user(fix->type, &fix32->type); | ||
1011 | err |= put_user(fix->type_aux, &fix32->type_aux); | ||
1012 | err |= put_user(fix->visual, &fix32->visual); | ||
1013 | err |= put_user(fix->xpanstep, &fix32->xpanstep); | ||
1014 | err |= put_user(fix->ypanstep, &fix32->ypanstep); | ||
1015 | err |= put_user(fix->ywrapstep, &fix32->ywrapstep); | ||
1016 | err |= put_user(fix->line_length, &fix32->line_length); | ||
1017 | |||
1018 | data = (__u32) (unsigned long) fix->mmio_start; | ||
1019 | err |= put_user(data, &fix32->mmio_start); | ||
1020 | |||
1021 | err |= put_user(fix->mmio_len, &fix32->mmio_len); | ||
1022 | err |= put_user(fix->accel, &fix32->accel); | ||
1023 | err |= copy_to_user(fix32->reserved, fix->reserved, | ||
1024 | sizeof(fix->reserved)); | ||
1025 | |||
1026 | return err; | ||
1027 | } | ||
1028 | |||
1029 | static int fb_get_fscreeninfo(struct inode *inode, struct file *file, | ||
1030 | unsigned int cmd, unsigned long arg) | ||
1031 | { | ||
1032 | mm_segment_t old_fs; | ||
1033 | struct fb_fix_screeninfo fix; | ||
1034 | struct fb_fix_screeninfo32 __user *fix32; | ||
1035 | int err; | ||
1036 | |||
1037 | fix32 = compat_ptr(arg); | ||
1038 | |||
1039 | old_fs = get_fs(); | ||
1040 | set_fs(KERNEL_DS); | ||
1041 | err = fb_ioctl(inode, file, cmd, (unsigned long) &fix); | ||
1042 | set_fs(old_fs); | ||
1043 | |||
1044 | if (!err) | ||
1045 | err = do_fscreeninfo_to_user(&fix, fix32); | ||
1046 | |||
1047 | return err; | ||
1048 | } | ||
1049 | |||
936 | static long | 1050 | static long |
937 | fb_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | 1051 | fb_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg) |
938 | { | 1052 | { |
939 | int fbidx = iminor(file->f_dentry->d_inode); | 1053 | struct inode *inode = file->f_dentry->d_inode; |
1054 | int fbidx = iminor(inode); | ||
940 | struct fb_info *info = registered_fb[fbidx]; | 1055 | struct fb_info *info = registered_fb[fbidx]; |
941 | struct fb_ops *fb = info->fbops; | 1056 | struct fb_ops *fb = info->fbops; |
942 | long ret; | 1057 | long ret = -ENOIOCTLCMD; |
943 | 1058 | ||
944 | if (fb->fb_compat_ioctl == NULL) | ||
945 | return -ENOIOCTLCMD; | ||
946 | lock_kernel(); | 1059 | lock_kernel(); |
947 | ret = fb->fb_compat_ioctl(file, cmd, arg, info); | 1060 | switch(cmd) { |
1061 | case FBIOGET_VSCREENINFO: | ||
1062 | case FBIOPUT_VSCREENINFO: | ||
1063 | case FBIOPAN_DISPLAY: | ||
1064 | case FBIOGET_CON2FBMAP: | ||
1065 | case FBIOPUT_CON2FBMAP: | ||
1066 | arg = (unsigned long) compat_ptr(arg); | ||
1067 | case FBIOBLANK: | ||
1068 | ret = fb_ioctl(inode, file, cmd, arg); | ||
1069 | break; | ||
1070 | |||
1071 | case FBIOGET_FSCREENINFO: | ||
1072 | ret = fb_get_fscreeninfo(inode, file, cmd, arg); | ||
1073 | break; | ||
1074 | |||
1075 | case FBIOGETCMAP: | ||
1076 | case FBIOPUTCMAP: | ||
1077 | ret = fb_getput_cmap(inode, file, cmd, arg); | ||
1078 | break; | ||
1079 | |||
1080 | default: | ||
1081 | if (fb->fb_compat_ioctl) | ||
1082 | ret = fb->fb_compat_ioctl(file, cmd, arg, info); | ||
1083 | break; | ||
1084 | } | ||
948 | unlock_kernel(); | 1085 | unlock_kernel(); |
949 | return ret; | 1086 | return ret; |
950 | } | 1087 | } |
diff --git a/fs/compat_ioctl.c b/fs/compat_ioctl.c index 71c9d45c0624..26300fccb4fc 100644 --- a/fs/compat_ioctl.c +++ b/fs/compat_ioctl.c | |||
@@ -840,146 +840,6 @@ static int hdio_getgeo(unsigned int fd, unsigned int cmd, unsigned long arg) | |||
840 | return err ? -EFAULT : 0; | 840 | return err ? -EFAULT : 0; |
841 | } | 841 | } |
842 | 842 | ||
843 | struct fb_fix_screeninfo32 { | ||
844 | char id[16]; | ||
845 | compat_caddr_t smem_start; | ||
846 | u32 smem_len; | ||
847 | u32 type; | ||
848 | u32 type_aux; | ||
849 | u32 visual; | ||
850 | u16 xpanstep; | ||
851 | u16 ypanstep; | ||
852 | u16 ywrapstep; | ||
853 | u32 line_length; | ||
854 | compat_caddr_t mmio_start; | ||
855 | u32 mmio_len; | ||
856 | u32 accel; | ||
857 | u16 reserved[3]; | ||
858 | }; | ||
859 | |||
860 | struct fb_cmap32 { | ||
861 | u32 start; | ||
862 | u32 len; | ||
863 | compat_caddr_t red; | ||
864 | compat_caddr_t green; | ||
865 | compat_caddr_t blue; | ||
866 | compat_caddr_t transp; | ||
867 | }; | ||
868 | |||
869 | static int fb_getput_cmap(unsigned int fd, unsigned int cmd, unsigned long arg) | ||
870 | { | ||
871 | struct fb_cmap_user __user *cmap; | ||
872 | struct fb_cmap32 __user *cmap32; | ||
873 | __u32 data; | ||
874 | int err; | ||
875 | |||
876 | cmap = compat_alloc_user_space(sizeof(*cmap)); | ||
877 | cmap32 = compat_ptr(arg); | ||
878 | |||
879 | if (copy_in_user(&cmap->start, &cmap32->start, 2 * sizeof(__u32))) | ||
880 | return -EFAULT; | ||
881 | |||
882 | if (get_user(data, &cmap32->red) || | ||
883 | put_user(compat_ptr(data), &cmap->red) || | ||
884 | get_user(data, &cmap32->green) || | ||
885 | put_user(compat_ptr(data), &cmap->green) || | ||
886 | get_user(data, &cmap32->blue) || | ||
887 | put_user(compat_ptr(data), &cmap->blue) || | ||
888 | get_user(data, &cmap32->transp) || | ||
889 | put_user(compat_ptr(data), &cmap->transp)) | ||
890 | return -EFAULT; | ||
891 | |||
892 | err = sys_ioctl(fd, cmd, (unsigned long) cmap); | ||
893 | |||
894 | if (!err) { | ||
895 | if (copy_in_user(&cmap32->start, | ||
896 | &cmap->start, | ||
897 | 2 * sizeof(__u32))) | ||
898 | err = -EFAULT; | ||
899 | } | ||
900 | return err; | ||
901 | } | ||
902 | |||
903 | static int do_fscreeninfo_to_user(struct fb_fix_screeninfo *fix, | ||
904 | struct fb_fix_screeninfo32 __user *fix32) | ||
905 | { | ||
906 | __u32 data; | ||
907 | int err; | ||
908 | |||
909 | err = copy_to_user(&fix32->id, &fix->id, sizeof(fix32->id)); | ||
910 | |||
911 | data = (__u32) (unsigned long) fix->smem_start; | ||
912 | err |= put_user(data, &fix32->smem_start); | ||
913 | |||
914 | err |= put_user(fix->smem_len, &fix32->smem_len); | ||
915 | err |= put_user(fix->type, &fix32->type); | ||
916 | err |= put_user(fix->type_aux, &fix32->type_aux); | ||
917 | err |= put_user(fix->visual, &fix32->visual); | ||
918 | err |= put_user(fix->xpanstep, &fix32->xpanstep); | ||
919 | err |= put_user(fix->ypanstep, &fix32->ypanstep); | ||
920 | err |= put_user(fix->ywrapstep, &fix32->ywrapstep); | ||
921 | err |= put_user(fix->line_length, &fix32->line_length); | ||
922 | |||
923 | data = (__u32) (unsigned long) fix->mmio_start; | ||
924 | err |= put_user(data, &fix32->mmio_start); | ||
925 | |||
926 | err |= put_user(fix->mmio_len, &fix32->mmio_len); | ||
927 | err |= put_user(fix->accel, &fix32->accel); | ||
928 | err |= copy_to_user(fix32->reserved, fix->reserved, | ||
929 | sizeof(fix->reserved)); | ||
930 | |||
931 | return err; | ||
932 | } | ||
933 | |||
934 | static int fb_get_fscreeninfo(unsigned int fd, unsigned int cmd, unsigned long arg) | ||
935 | { | ||
936 | mm_segment_t old_fs; | ||
937 | struct fb_fix_screeninfo fix; | ||
938 | struct fb_fix_screeninfo32 __user *fix32; | ||
939 | int err; | ||
940 | |||
941 | fix32 = compat_ptr(arg); | ||
942 | |||
943 | old_fs = get_fs(); | ||
944 | set_fs(KERNEL_DS); | ||
945 | err = sys_ioctl(fd, cmd, (unsigned long) &fix); | ||
946 | set_fs(old_fs); | ||
947 | |||
948 | if (!err) | ||
949 | err = do_fscreeninfo_to_user(&fix, fix32); | ||
950 | |||
951 | return err; | ||
952 | } | ||
953 | |||
954 | static int fb_ioctl_trans(unsigned int fd, unsigned int cmd, unsigned long arg) | ||
955 | { | ||
956 | int err; | ||
957 | |||
958 | switch (cmd) { | ||
959 | case FBIOGET_FSCREENINFO: | ||
960 | err = fb_get_fscreeninfo(fd,cmd, arg); | ||
961 | break; | ||
962 | |||
963 | case FBIOGETCMAP: | ||
964 | case FBIOPUTCMAP: | ||
965 | err = fb_getput_cmap(fd, cmd, arg); | ||
966 | break; | ||
967 | |||
968 | default: | ||
969 | do { | ||
970 | static int count; | ||
971 | if (++count <= 20) | ||
972 | printk("%s: Unknown fb ioctl cmd fd(%d) " | ||
973 | "cmd(%08x) arg(%08lx)\n", | ||
974 | __FUNCTION__, fd, cmd, arg); | ||
975 | } while(0); | ||
976 | err = -ENOSYS; | ||
977 | break; | ||
978 | }; | ||
979 | |||
980 | return err; | ||
981 | } | ||
982 | |||
983 | static int hdio_ioctl_trans(unsigned int fd, unsigned int cmd, unsigned long arg) | 843 | static int hdio_ioctl_trans(unsigned int fd, unsigned int cmd, unsigned long arg) |
984 | { | 844 | { |
985 | mm_segment_t old_fs = get_fs(); | 845 | mm_segment_t old_fs = get_fs(); |
@@ -2953,10 +2813,7 @@ HANDLE_IOCTL(BLKGETSIZE, w_long) | |||
2953 | HANDLE_IOCTL(0x1260, broken_blkgetsize) | 2813 | HANDLE_IOCTL(0x1260, broken_blkgetsize) |
2954 | HANDLE_IOCTL(BLKFRAGET, w_long) | 2814 | HANDLE_IOCTL(BLKFRAGET, w_long) |
2955 | HANDLE_IOCTL(BLKSECTGET, w_long) | 2815 | HANDLE_IOCTL(BLKSECTGET, w_long) |
2956 | HANDLE_IOCTL(FBIOGET_FSCREENINFO, fb_ioctl_trans) | ||
2957 | HANDLE_IOCTL(BLKPG, blkpg_ioctl_trans) | 2816 | HANDLE_IOCTL(BLKPG, blkpg_ioctl_trans) |
2958 | HANDLE_IOCTL(FBIOGETCMAP, fb_ioctl_trans) | ||
2959 | HANDLE_IOCTL(FBIOPUTCMAP, fb_ioctl_trans) | ||
2960 | HANDLE_IOCTL(HDIO_GET_KEEPSETTINGS, hdio_ioctl_trans) | 2817 | HANDLE_IOCTL(HDIO_GET_KEEPSETTINGS, hdio_ioctl_trans) |
2961 | HANDLE_IOCTL(HDIO_GET_UNMASKINTR, hdio_ioctl_trans) | 2818 | HANDLE_IOCTL(HDIO_GET_UNMASKINTR, hdio_ioctl_trans) |
2962 | HANDLE_IOCTL(HDIO_GET_DMA, hdio_ioctl_trans) | 2819 | HANDLE_IOCTL(HDIO_GET_DMA, hdio_ioctl_trans) |
diff --git a/include/linux/compat_ioctl.h b/include/linux/compat_ioctl.h index 4c63c2963019..2209ad3499a3 100644 --- a/include/linux/compat_ioctl.h +++ b/include/linux/compat_ioctl.h | |||
@@ -56,13 +56,6 @@ ULONG_IOCTL(TIOCSCTTY) | |||
56 | COMPATIBLE_IOCTL(TIOCGPTN) | 56 | COMPATIBLE_IOCTL(TIOCGPTN) |
57 | COMPATIBLE_IOCTL(TIOCSPTLCK) | 57 | COMPATIBLE_IOCTL(TIOCSPTLCK) |
58 | COMPATIBLE_IOCTL(TIOCSERGETLSR) | 58 | COMPATIBLE_IOCTL(TIOCSERGETLSR) |
59 | /* Big F */ | ||
60 | COMPATIBLE_IOCTL(FBIOBLANK) | ||
61 | COMPATIBLE_IOCTL(FBIOGET_VSCREENINFO) | ||
62 | COMPATIBLE_IOCTL(FBIOPUT_VSCREENINFO) | ||
63 | COMPATIBLE_IOCTL(FBIOPAN_DISPLAY) | ||
64 | COMPATIBLE_IOCTL(FBIOGET_CON2FBMAP) | ||
65 | COMPATIBLE_IOCTL(FBIOPUT_CON2FBMAP) | ||
66 | /* Little f */ | 59 | /* Little f */ |
67 | COMPATIBLE_IOCTL(FIOCLEX) | 60 | COMPATIBLE_IOCTL(FIOCLEX) |
68 | COMPATIBLE_IOCTL(FIONCLEX) | 61 | COMPATIBLE_IOCTL(FIONCLEX) |