aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/video/fbmem.c147
-rw-r--r--fs/compat_ioctl.c143
-rw-r--r--include/linux/compat_ioctl.h7
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
937struct 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
954struct 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
963static 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
998static 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
1029static 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
936static long 1050static long
937fb_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg) 1051fb_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
843struct 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
860struct 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
869static 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
903static 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
934static 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
954static 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
983static int hdio_ioctl_trans(unsigned int fd, unsigned int cmd, unsigned long arg) 843static 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)
2953HANDLE_IOCTL(0x1260, broken_blkgetsize) 2813HANDLE_IOCTL(0x1260, broken_blkgetsize)
2954HANDLE_IOCTL(BLKFRAGET, w_long) 2814HANDLE_IOCTL(BLKFRAGET, w_long)
2955HANDLE_IOCTL(BLKSECTGET, w_long) 2815HANDLE_IOCTL(BLKSECTGET, w_long)
2956HANDLE_IOCTL(FBIOGET_FSCREENINFO, fb_ioctl_trans)
2957HANDLE_IOCTL(BLKPG, blkpg_ioctl_trans) 2816HANDLE_IOCTL(BLKPG, blkpg_ioctl_trans)
2958HANDLE_IOCTL(FBIOGETCMAP, fb_ioctl_trans)
2959HANDLE_IOCTL(FBIOPUTCMAP, fb_ioctl_trans)
2960HANDLE_IOCTL(HDIO_GET_KEEPSETTINGS, hdio_ioctl_trans) 2817HANDLE_IOCTL(HDIO_GET_KEEPSETTINGS, hdio_ioctl_trans)
2961HANDLE_IOCTL(HDIO_GET_UNMASKINTR, hdio_ioctl_trans) 2818HANDLE_IOCTL(HDIO_GET_UNMASKINTR, hdio_ioctl_trans)
2962HANDLE_IOCTL(HDIO_GET_DMA, hdio_ioctl_trans) 2819HANDLE_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)
56COMPATIBLE_IOCTL(TIOCGPTN) 56COMPATIBLE_IOCTL(TIOCGPTN)
57COMPATIBLE_IOCTL(TIOCSPTLCK) 57COMPATIBLE_IOCTL(TIOCSPTLCK)
58COMPATIBLE_IOCTL(TIOCSERGETLSR) 58COMPATIBLE_IOCTL(TIOCSERGETLSR)
59/* Big F */
60COMPATIBLE_IOCTL(FBIOBLANK)
61COMPATIBLE_IOCTL(FBIOGET_VSCREENINFO)
62COMPATIBLE_IOCTL(FBIOPUT_VSCREENINFO)
63COMPATIBLE_IOCTL(FBIOPAN_DISPLAY)
64COMPATIBLE_IOCTL(FBIOGET_CON2FBMAP)
65COMPATIBLE_IOCTL(FBIOPUT_CON2FBMAP)
66/* Little f */ 59/* Little f */
67COMPATIBLE_IOCTL(FIOCLEX) 60COMPATIBLE_IOCTL(FIOCLEX)
68COMPATIBLE_IOCTL(FIONCLEX) 61COMPATIBLE_IOCTL(FIONCLEX)