@@ -467,7 +467,7 @@ EXPORT_SYMBOL(generic_block_fiemap);
467
467
* Only the l_start, l_len and l_whence fields of the 'struct space_resv'
468
468
* are used here, rest are ignored.
469
469
*/
470
- int ioctl_preallocate (struct file * filp , int mode , void __user * argp )
470
+ static int ioctl_preallocate (struct file * filp , int mode , void __user * argp )
471
471
{
472
472
struct inode * inode = file_inode (filp );
473
473
struct space_resv sr ;
@@ -495,8 +495,8 @@ int ioctl_preallocate(struct file *filp, int mode, void __user *argp)
495
495
/* on ia32 l_start is on a 32-bit boundary */
496
496
#if defined CONFIG_COMPAT && defined(CONFIG_X86_64 )
497
497
/* just account for different alignment */
498
- int compat_ioctl_preallocate (struct file * file , int mode ,
499
- struct space_resv_32 __user * argp )
498
+ static int compat_ioctl_preallocate (struct file * file , int mode ,
499
+ struct space_resv_32 __user * argp )
500
500
{
501
501
struct inode * inode = file_inode (file );
502
502
struct space_resv_32 sr ;
@@ -521,11 +521,9 @@ int compat_ioctl_preallocate(struct file *file, int mode,
521
521
}
522
522
#endif
523
523
524
- static int file_ioctl (struct file * filp , unsigned int cmd ,
525
- unsigned long arg )
524
+ static int file_ioctl (struct file * filp , unsigned int cmd , int __user * p )
526
525
{
527
526
struct inode * inode = file_inode (filp );
528
- int __user * p = (int __user * )arg ;
529
527
530
528
switch (cmd ) {
531
529
case FIBMAP :
@@ -542,7 +540,7 @@ static int file_ioctl(struct file *filp, unsigned int cmd,
542
540
return ioctl_preallocate (filp , FALLOC_FL_ZERO_RANGE , p );
543
541
}
544
542
545
- return vfs_ioctl ( filp , cmd , arg ) ;
543
+ return - ENOIOCTLCMD ;
546
544
}
547
545
548
546
static int ioctl_fionbio (struct file * filp , int __user * argp )
@@ -661,53 +659,48 @@ static int ioctl_file_dedupe_range(struct file *file,
661
659
}
662
660
663
661
/*
664
- * When you add any new common ioctls to the switches above and below
665
- * please update compat_sys_ioctl() too.
666
- *
667
662
* do_vfs_ioctl() is not for drivers and not intended to be EXPORT_SYMBOL()'d.
668
663
* It's just a simple helper for sys_ioctl and compat_sys_ioctl.
664
+ *
665
+ * When you add any new common ioctls to the switches above and below,
666
+ * please ensure they have compatible arguments in compat mode.
669
667
*/
670
- int do_vfs_ioctl (struct file * filp , unsigned int fd , unsigned int cmd ,
671
- unsigned long arg )
668
+ static int do_vfs_ioctl (struct file * filp , unsigned int fd ,
669
+ unsigned int cmd , unsigned long arg )
672
670
{
673
- int error = 0 ;
674
671
void __user * argp = (void __user * )arg ;
675
672
struct inode * inode = file_inode (filp );
676
673
677
674
switch (cmd ) {
678
675
case FIOCLEX :
679
676
set_close_on_exec (fd , 1 );
680
- break ;
677
+ return 0 ;
681
678
682
679
case FIONCLEX :
683
680
set_close_on_exec (fd , 0 );
684
- break ;
681
+ return 0 ;
685
682
686
683
case FIONBIO :
687
- error = ioctl_fionbio (filp , argp );
688
- break ;
684
+ return ioctl_fionbio (filp , argp );
689
685
690
686
case FIOASYNC :
691
- error = ioctl_fioasync (fd , filp , argp );
692
- break ;
687
+ return ioctl_fioasync (fd , filp , argp );
693
688
694
689
case FIOQSIZE :
695
690
if (S_ISDIR (inode -> i_mode ) || S_ISREG (inode -> i_mode ) ||
696
691
S_ISLNK (inode -> i_mode )) {
697
692
loff_t res = inode_get_bytes (inode );
698
- error = copy_to_user (argp , & res , sizeof (res )) ?
699
- - EFAULT : 0 ;
700
- } else
701
- error = - ENOTTY ;
702
- break ;
693
+ return copy_to_user (argp , & res , sizeof (res )) ?
694
+ - EFAULT : 0 ;
695
+ }
696
+
697
+ return - ENOTTY ;
703
698
704
699
case FIFREEZE :
705
- error = ioctl_fsfreeze (filp );
706
- break ;
700
+ return ioctl_fsfreeze (filp );
707
701
708
702
case FITHAW :
709
- error = ioctl_fsthaw (filp );
710
- break ;
703
+ return ioctl_fsthaw (filp );
711
704
712
705
case FS_IOC_FIEMAP :
713
706
return ioctl_fiemap (filp , argp );
@@ -716,6 +709,7 @@ int do_vfs_ioctl(struct file *filp, unsigned int fd, unsigned int cmd,
716
709
/* anon_bdev filesystems may not have a block size */
717
710
if (!inode -> i_sb -> s_blocksize )
718
711
return - EINVAL ;
712
+
719
713
return put_user (inode -> i_sb -> s_blocksize , (int __user * )argp );
720
714
721
715
case FICLONE :
@@ -729,24 +723,30 @@ int do_vfs_ioctl(struct file *filp, unsigned int fd, unsigned int cmd,
729
723
730
724
default :
731
725
if (S_ISREG (inode -> i_mode ))
732
- error = file_ioctl (filp , cmd , arg );
733
- else
734
- error = vfs_ioctl (filp , cmd , arg );
726
+ return file_ioctl (filp , cmd , argp );
735
727
break ;
736
728
}
737
- return error ;
729
+
730
+ return - ENOIOCTLCMD ;
738
731
}
739
732
740
733
int ksys_ioctl (unsigned int fd , unsigned int cmd , unsigned long arg )
741
734
{
742
- int error ;
743
735
struct fd f = fdget (fd );
736
+ int error ;
744
737
745
738
if (!f .file )
746
739
return - EBADF ;
740
+
747
741
error = security_file_ioctl (f .file , cmd , arg );
748
- if (!error )
749
- error = do_vfs_ioctl (f .file , fd , cmd , arg );
742
+ if (error )
743
+ goto out ;
744
+
745
+ error = do_vfs_ioctl (f .file , fd , cmd , arg );
746
+ if (error == - ENOIOCTLCMD )
747
+ error = vfs_ioctl (f .file , cmd , arg );
748
+
749
+ out :
750
750
fdput (f );
751
751
return error ;
752
752
}
@@ -790,92 +790,63 @@ long compat_ptr_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
790
790
EXPORT_SYMBOL (compat_ptr_ioctl );
791
791
792
792
COMPAT_SYSCALL_DEFINE3 (ioctl , unsigned int , fd , unsigned int , cmd ,
793
- compat_ulong_t , arg32 )
793
+ compat_ulong_t , arg )
794
794
{
795
- unsigned long arg = arg32 ;
796
795
struct fd f = fdget (fd );
797
- int error = - EBADF ;
796
+ int error ;
797
+
798
798
if (!f .file )
799
- goto out ;
799
+ return - EBADF ;
800
800
801
801
/* RED-PEN how should LSM module know it's handling 32bit? */
802
802
error = security_file_ioctl (f .file , cmd , arg );
803
803
if (error )
804
- goto out_fput ;
804
+ goto out ;
805
805
806
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 :
807
+ /* FICLONE takes an int argument, so don't use compat_ptr() */
812
808
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 */
809
+ error = ioctl_file_clone (f .file , arg , 0 , 0 , 0 );
810
+ break ;
811
+
839
812
#if defined(CONFIG_X86_64 )
813
+ /* these get messy on amd64 due to alignment differences */
840
814
case FS_IOC_RESVSP_32 :
841
815
case FS_IOC_RESVSP64_32 :
842
816
error = compat_ioctl_preallocate (f .file , 0 , compat_ptr (arg ));
843
- goto out_fput ;
817
+ break ;
844
818
case FS_IOC_UNRESVSP_32 :
845
819
case FS_IOC_UNRESVSP64_32 :
846
820
error = compat_ioctl_preallocate (f .file , FALLOC_FL_PUNCH_HOLE ,
847
821
compat_ptr (arg ));
848
- goto out_fput ;
822
+ break ;
849
823
case FS_IOC_ZERO_RANGE_32 :
850
824
error = compat_ioctl_preallocate (f .file , FALLOC_FL_ZERO_RANGE ,
851
825
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 ;
826
+ break ;
860
827
#endif
861
828
829
+ /*
830
+ * everything else in do_vfs_ioctl() takes either a compatible
831
+ * pointer argument or no argument -- call it with a modified
832
+ * argument.
833
+ */
862
834
default :
863
- if (f .file -> f_op -> compat_ioctl ) {
835
+ error = do_vfs_ioctl (f .file , fd , cmd ,
836
+ (unsigned long )compat_ptr (arg ));
837
+ if (error != - ENOIOCTLCMD )
838
+ break ;
839
+
840
+ if (f .file -> f_op -> compat_ioctl )
864
841
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 ;
842
+ if (error == - ENOIOCTLCMD )
843
+ error = - ENOTTY ;
844
+ break ;
870
845
}
871
846
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
847
out :
848
+ fdput (f );
849
+
879
850
return error ;
880
851
}
881
852
#endif
0 commit comments