@@ -788,4 +788,94 @@ long compat_ptr_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
788
788
return file -> f_op -> unlocked_ioctl (file , cmd , (unsigned long )compat_ptr (arg ));
789
789
}
790
790
EXPORT_SYMBOL (compat_ptr_ioctl );
791
+
792
+ COMPAT_SYSCALL_DEFINE3 (ioctl , unsigned int , fd , unsigned int , cmd ,
793
+ compat_ulong_t , arg32 )
794
+ {
795
+ unsigned long arg = arg32 ;
796
+ struct fd f = fdget (fd );
797
+ int error = - EBADF ;
798
+ if (!f .file )
799
+ goto out ;
800
+
801
+ /* RED-PEN how should LSM module know it's handling 32bit? */
802
+ error = security_file_ioctl (f .file , cmd , arg );
803
+ if (error )
804
+ goto out_fput ;
805
+
806
+ switch (cmd ) {
807
+ /* these are never seen by ->ioctl(), no argument or int argument */
808
+ case FIOCLEX :
809
+ case FIONCLEX :
810
+ case FIFREEZE :
811
+ case FITHAW :
812
+ case FICLONE :
813
+ goto do_ioctl ;
814
+ /* these are never seen by ->ioctl(), pointer argument */
815
+ case FIONBIO :
816
+ case FIOASYNC :
817
+ case FIOQSIZE :
818
+ case FS_IOC_FIEMAP :
819
+ case FIGETBSZ :
820
+ case FICLONERANGE :
821
+ case FIDEDUPERANGE :
822
+ goto found_handler ;
823
+ /*
824
+ * The next group is the stuff handled inside file_ioctl().
825
+ * For regular files these never reach ->ioctl(); for
826
+ * devices, sockets, etc. they do and one (FIONREAD) is
827
+ * even accepted in some cases. In all those cases
828
+ * argument has the same type, so we can handle these
829
+ * here, shunting them towards do_vfs_ioctl().
830
+ * ->compat_ioctl() will never see any of those.
831
+ */
832
+ /* pointer argument, never actually handled by ->ioctl() */
833
+ case FIBMAP :
834
+ goto found_handler ;
835
+ /* handled by some ->ioctl(); always a pointer to int */
836
+ case FIONREAD :
837
+ goto found_handler ;
838
+ /* these get messy on amd64 due to alignment differences */
839
+ #if defined(CONFIG_X86_64 )
840
+ case FS_IOC_RESVSP_32 :
841
+ case FS_IOC_RESVSP64_32 :
842
+ error = compat_ioctl_preallocate (f .file , 0 , compat_ptr (arg ));
843
+ goto out_fput ;
844
+ case FS_IOC_UNRESVSP_32 :
845
+ case FS_IOC_UNRESVSP64_32 :
846
+ error = compat_ioctl_preallocate (f .file , FALLOC_FL_PUNCH_HOLE ,
847
+ compat_ptr (arg ));
848
+ goto out_fput ;
849
+ case FS_IOC_ZERO_RANGE_32 :
850
+ error = compat_ioctl_preallocate (f .file , FALLOC_FL_ZERO_RANGE ,
851
+ compat_ptr (arg ));
852
+ goto out_fput ;
853
+ #else
854
+ case FS_IOC_RESVSP :
855
+ case FS_IOC_RESVSP64 :
856
+ case FS_IOC_UNRESVSP :
857
+ case FS_IOC_UNRESVSP64 :
858
+ case FS_IOC_ZERO_RANGE :
859
+ goto found_handler ;
860
+ #endif
861
+
862
+ default :
863
+ if (f .file -> f_op -> compat_ioctl ) {
864
+ error = f .file -> f_op -> compat_ioctl (f .file , cmd , arg );
865
+ if (error != - ENOIOCTLCMD )
866
+ goto out_fput ;
867
+ }
868
+ error = - ENOTTY ;
869
+ goto out_fput ;
870
+ }
871
+
872
+ found_handler :
873
+ arg = (unsigned long )compat_ptr (arg );
874
+ do_ioctl :
875
+ error = do_vfs_ioctl (f .file , fd , cmd , arg );
876
+ out_fput :
877
+ fdput (f );
878
+ out :
879
+ return error ;
880
+ }
791
881
#endif
0 commit comments