@@ -2651,6 +2651,81 @@ long tty_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
2651
2651
}
2652
2652
2653
2653
#ifdef CONFIG_COMPAT
2654
+
2655
+ struct serial_struct32 {
2656
+ compat_int_t type ;
2657
+ compat_int_t line ;
2658
+ compat_uint_t port ;
2659
+ compat_int_t irq ;
2660
+ compat_int_t flags ;
2661
+ compat_int_t xmit_fifo_size ;
2662
+ compat_int_t custom_divisor ;
2663
+ compat_int_t baud_base ;
2664
+ unsigned short close_delay ;
2665
+ char io_type ;
2666
+ char reserved_char [1 ];
2667
+ compat_int_t hub6 ;
2668
+ unsigned short closing_wait ; /* time to wait before closing */
2669
+ unsigned short closing_wait2 ; /* no longer used... */
2670
+ compat_uint_t iomem_base ;
2671
+ unsigned short iomem_reg_shift ;
2672
+ unsigned int port_high ;
2673
+ /* compat_ulong_t iomap_base FIXME */
2674
+ compat_int_t reserved [1 ];
2675
+ };
2676
+
2677
+ static int compat_tty_tiocsserial (struct tty_struct * tty ,
2678
+ struct serial_struct32 __user * ss )
2679
+ {
2680
+ static DEFINE_RATELIMIT_STATE (depr_flags ,
2681
+ DEFAULT_RATELIMIT_INTERVAL ,
2682
+ DEFAULT_RATELIMIT_BURST ) ;
2683
+ char comm [TASK_COMM_LEN ];
2684
+ struct serial_struct32 v32 ;
2685
+ struct serial_struct v ;
2686
+ int flags ;
2687
+
2688
+ if (copy_from_user (& v32 , ss , sizeof (struct serial_struct32 )))
2689
+ return - EFAULT ;
2690
+
2691
+ memcpy (& v , & v32 , offsetof(struct serial_struct32 , iomem_base ));
2692
+ v .iomem_base = compat_ptr (v32 .iomem_base );
2693
+ v .iomem_reg_shift = v32 .iomem_reg_shift ;
2694
+ v .port_high = v32 .port_high ;
2695
+ v .iomap_base = 0 ;
2696
+
2697
+ flags = v .flags & ASYNC_DEPRECATED ;
2698
+
2699
+ if (flags && __ratelimit (& depr_flags ))
2700
+ pr_warn ("%s: '%s' is using deprecated serial flags (with no effect): %.8x\n" ,
2701
+ __func__ , get_task_comm (comm , current ), flags );
2702
+ if (!tty -> ops -> set_serial )
2703
+ return - ENOTTY ;
2704
+ return tty -> ops -> set_serial (tty , & v );
2705
+ }
2706
+
2707
+ static int compat_tty_tiocgserial (struct tty_struct * tty ,
2708
+ struct serial_struct32 __user * ss )
2709
+ {
2710
+ struct serial_struct32 v32 ;
2711
+ struct serial_struct v ;
2712
+ int err ;
2713
+ memset (& v , 0 , sizeof (struct serial_struct ));
2714
+
2715
+ if (!tty -> ops -> set_serial )
2716
+ return - ENOTTY ;
2717
+ err = tty -> ops -> get_serial (tty , & v );
2718
+ if (!err ) {
2719
+ memcpy (& v32 , & v , offsetof(struct serial_struct32 , iomem_base ));
2720
+ v32 .iomem_base = (unsigned long )v .iomem_base >> 32 ?
2721
+ 0xfffffff : ptr_to_compat (v .iomem_base );
2722
+ v32 .iomem_reg_shift = v .iomem_reg_shift ;
2723
+ v32 .port_high = v .port_high ;
2724
+ if (copy_to_user (ss , & v32 , sizeof (struct serial_struct32 )))
2725
+ err = - EFAULT ;
2726
+ }
2727
+ return err ;
2728
+ }
2654
2729
static long tty_compat_ioctl (struct file * file , unsigned int cmd ,
2655
2730
unsigned long arg )
2656
2731
{
@@ -2736,6 +2811,12 @@ static long tty_compat_ioctl(struct file *file, unsigned int cmd,
2736
2811
if (tty_paranoia_check (tty , file_inode (file ), "tty_ioctl" ))
2737
2812
return - EINVAL ;
2738
2813
2814
+ switch (cmd ) {
2815
+ case TIOCSSERIAL :
2816
+ return compat_tty_tiocsserial (tty , compat_ptr (arg ));
2817
+ case TIOCGSERIAL :
2818
+ return compat_tty_tiocgserial (tty , compat_ptr (arg ));
2819
+ }
2739
2820
if (tty -> ops -> compat_ioctl ) {
2740
2821
retval = tty -> ops -> compat_ioctl (tty , cmd , arg );
2741
2822
if (retval != - ENOIOCTLCMD )
0 commit comments