Skip to content

Commit f0193d3

Browse files
author
Al Viro
committed
change semantics of ldisc ->compat_ioctl()
First of all, make it return int. Returning long when native method had never allowed that is ridiculous and inconvenient. More importantly, change the caller; if ldisc ->compat_ioctl() is NULL or returns -ENOIOCTLCMD, tty_compat_ioctl() will try to feed cmd and compat_ptr(arg) to ldisc's native ->ioctl(). That simplifies ->compat_ioctl() instances quite a bit - they only need to deal with ioctls that are neither generic tty ones (those would get shunted off to tty_ioctl()) nor simple compat pointer ones. Note that something like TCFLSH won't reach ->compat_ioctl(), even if ldisc ->ioctl() does handle it - it will be recognized earlier and passed to tty_ioctl() (and ultimately - ldisc ->ioctl()). For many ldiscs it means that NULL ->compat_ioctl() does the right thing. Those where it won't serve (see e.g. n_r3964.c) are also easily dealt with - we need to handle the numeric-argument ioctls (calling the native instance) and, if such would exist, the ioctls that need layout conversion, etc. All in-tree ldiscs dealt with. Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
1 parent 7ee3296 commit f0193d3

File tree

11 files changed

+36
-100
lines changed

11 files changed

+36
-100
lines changed

drivers/bluetooth/hci_ldisc.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -821,6 +821,7 @@ static int __init hci_uart_init(void)
821821
hci_uart_ldisc.read = hci_uart_tty_read;
822822
hci_uart_ldisc.write = hci_uart_tty_write;
823823
hci_uart_ldisc.ioctl = hci_uart_tty_ioctl;
824+
hci_uart_ldisc.compat_ioctl = hci_uart_tty_ioctl;
824825
hci_uart_ldisc.poll = hci_uart_tty_poll;
825826
hci_uart_ldisc.receive_buf = hci_uart_tty_receive;
826827
hci_uart_ldisc.write_wakeup = hci_uart_tty_wakeup;

drivers/input/serio/serport.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -226,7 +226,7 @@ static int serport_ldisc_ioctl(struct tty_struct *tty, struct file *file,
226226

227227
#ifdef CONFIG_COMPAT
228228
#define COMPAT_SPIOCSTYPE _IOW('q', 0x01, compat_ulong_t)
229-
static long serport_ldisc_compat_ioctl(struct tty_struct *tty,
229+
static int serport_ldisc_compat_ioctl(struct tty_struct *tty,
230230
struct file *file,
231231
unsigned int cmd, unsigned long arg)
232232
{

drivers/net/hamradio/6pack.c

Lines changed: 0 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,6 @@
3434
#include <linux/ip.h>
3535
#include <linux/tcp.h>
3636
#include <linux/semaphore.h>
37-
#include <linux/compat.h>
3837
#include <linux/refcount.h>
3938

4039
#define SIXPACK_VERSION "Revision: 0.3.0"
@@ -752,33 +751,13 @@ static int sixpack_ioctl(struct tty_struct *tty, struct file *file,
752751
return err;
753752
}
754753

755-
#ifdef CONFIG_COMPAT
756-
static long sixpack_compat_ioctl(struct tty_struct * tty, struct file * file,
757-
unsigned int cmd, unsigned long arg)
758-
{
759-
switch (cmd) {
760-
case SIOCGIFNAME:
761-
case SIOCGIFENCAP:
762-
case SIOCSIFENCAP:
763-
case SIOCSIFHWADDR:
764-
return sixpack_ioctl(tty, file, cmd,
765-
(unsigned long)compat_ptr(arg));
766-
}
767-
768-
return -ENOIOCTLCMD;
769-
}
770-
#endif
771-
772754
static struct tty_ldisc_ops sp_ldisc = {
773755
.owner = THIS_MODULE,
774756
.magic = TTY_LDISC_MAGIC,
775757
.name = "6pack",
776758
.open = sixpack_open,
777759
.close = sixpack_close,
778760
.ioctl = sixpack_ioctl,
779-
#ifdef CONFIG_COMPAT
780-
.compat_ioctl = sixpack_compat_ioctl,
781-
#endif
782761
.receive_buf = sixpack_receive_buf,
783762
.write_wakeup = sixpack_write_wakeup,
784763
};

drivers/net/hamradio/mkiss.c

Lines changed: 0 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,6 @@
3535
#include <linux/skbuff.h>
3636
#include <linux/if_arp.h>
3737
#include <linux/jiffies.h>
38-
#include <linux/compat.h>
3938

4039
#include <net/ax25.h>
4140

@@ -875,23 +874,6 @@ static int mkiss_ioctl(struct tty_struct *tty, struct file *file,
875874
return err;
876875
}
877876

878-
#ifdef CONFIG_COMPAT
879-
static long mkiss_compat_ioctl(struct tty_struct *tty, struct file *file,
880-
unsigned int cmd, unsigned long arg)
881-
{
882-
switch (cmd) {
883-
case SIOCGIFNAME:
884-
case SIOCGIFENCAP:
885-
case SIOCSIFENCAP:
886-
case SIOCSIFHWADDR:
887-
return mkiss_ioctl(tty, file, cmd,
888-
(unsigned long)compat_ptr(arg));
889-
}
890-
891-
return -ENOIOCTLCMD;
892-
}
893-
#endif
894-
895877
/*
896878
* Handle the 'receiver data ready' interrupt.
897879
* This function is called by the 'tty_io' module in the kernel when
@@ -966,9 +948,6 @@ static struct tty_ldisc_ops ax_ldisc = {
966948
.open = mkiss_open,
967949
.close = mkiss_close,
968950
.ioctl = mkiss_ioctl,
969-
#ifdef CONFIG_COMPAT
970-
.compat_ioctl = mkiss_compat_ioctl,
971-
#endif
972951
.receive_buf = mkiss_receive_buf,
973952
.write_wakeup = mkiss_write_wakeup
974953
};

drivers/net/slip/slip.c

Lines changed: 0 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,6 @@
7979
#include <linux/rtnetlink.h>
8080
#include <linux/if_arp.h>
8181
#include <linux/if_slip.h>
82-
#include <linux/compat.h>
8382
#include <linux/delay.h>
8483
#include <linux/init.h>
8584
#include <linux/slab.h>
@@ -1167,27 +1166,6 @@ static int slip_ioctl(struct tty_struct *tty, struct file *file,
11671166
}
11681167
}
11691168

1170-
#ifdef CONFIG_COMPAT
1171-
static long slip_compat_ioctl(struct tty_struct *tty, struct file *file,
1172-
unsigned int cmd, unsigned long arg)
1173-
{
1174-
switch (cmd) {
1175-
case SIOCGIFNAME:
1176-
case SIOCGIFENCAP:
1177-
case SIOCSIFENCAP:
1178-
case SIOCSIFHWADDR:
1179-
case SIOCSKEEPALIVE:
1180-
case SIOCGKEEPALIVE:
1181-
case SIOCSOUTFILL:
1182-
case SIOCGOUTFILL:
1183-
return slip_ioctl(tty, file, cmd,
1184-
(unsigned long)compat_ptr(arg));
1185-
}
1186-
1187-
return -ENOIOCTLCMD;
1188-
}
1189-
#endif
1190-
11911169
/* VSV changes start here */
11921170
#ifdef CONFIG_SLIP_SMART
11931171
/* function do_ioctl called from net/core/dev.c
@@ -1280,9 +1258,6 @@ static struct tty_ldisc_ops sl_ldisc = {
12801258
.close = slip_close,
12811259
.hangup = slip_hangup,
12821260
.ioctl = slip_ioctl,
1283-
#ifdef CONFIG_COMPAT
1284-
.compat_ioctl = slip_compat_ioctl,
1285-
#endif
12861261
.receive_buf = slip_receive_buf,
12871262
.write_wakeup = slip_write_wakeup,
12881263
};

drivers/net/wan/x25_asy.c

Lines changed: 0 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,6 @@
3333
#include <linux/lapb.h>
3434
#include <linux/init.h>
3535
#include <linux/rtnetlink.h>
36-
#include <linux/compat.h>
3736
#include <linux/slab.h>
3837
#include <net/x25device.h>
3938
#include "x25_asy.h"
@@ -703,21 +702,6 @@ static int x25_asy_ioctl(struct tty_struct *tty, struct file *file,
703702
}
704703
}
705704

706-
#ifdef CONFIG_COMPAT
707-
static long x25_asy_compat_ioctl(struct tty_struct *tty, struct file *file,
708-
unsigned int cmd, unsigned long arg)
709-
{
710-
switch (cmd) {
711-
case SIOCGIFNAME:
712-
case SIOCSIFHWADDR:
713-
return x25_asy_ioctl(tty, file, cmd,
714-
(unsigned long)compat_ptr(arg));
715-
}
716-
717-
return -ENOIOCTLCMD;
718-
}
719-
#endif
720-
721705
static int x25_asy_open_dev(struct net_device *dev)
722706
{
723707
struct x25_asy *sl = netdev_priv(dev);
@@ -769,9 +753,6 @@ static struct tty_ldisc_ops x25_ldisc = {
769753
.open = x25_asy_open_tty,
770754
.close = x25_asy_close_tty,
771755
.ioctl = x25_asy_ioctl,
772-
#ifdef CONFIG_COMPAT
773-
.compat_ioctl = x25_asy_compat_ioctl,
774-
#endif
775756
.receive_buf = x25_asy_receive_buf,
776757
.write_wakeup = x25_asy_write_wakeup,
777758
};

drivers/tty/n_gsm.c

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2614,14 +2614,6 @@ static int gsmld_ioctl(struct tty_struct *tty, struct file *file,
26142614
}
26152615
}
26162616

2617-
#ifdef CONFIG_COMPAT
2618-
static long gsmld_compat_ioctl(struct tty_struct *tty, struct file *file,
2619-
unsigned int cmd, unsigned long arg)
2620-
{
2621-
return gsmld_ioctl(tty, file, cmd, arg);
2622-
}
2623-
#endif
2624-
26252617
/*
26262618
* Network interface
26272619
*
@@ -2833,9 +2825,6 @@ static struct tty_ldisc_ops tty_ldisc_packet = {
28332825
.flush_buffer = gsmld_flush_buffer,
28342826
.read = gsmld_read,
28352827
.write = gsmld_write,
2836-
#ifdef CONFIG_COMPAT
2837-
.compat_ioctl = gsmld_compat_ioctl,
2838-
#endif
28392828
.ioctl = gsmld_ioctl,
28402829
.poll = gsmld_poll,
28412830
.receive_buf = gsmld_receive_buf,

drivers/tty/n_r3964.c

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,10 @@ static ssize_t r3964_write(struct tty_struct *tty, struct file *file,
134134
const unsigned char *buf, size_t nr);
135135
static int r3964_ioctl(struct tty_struct *tty, struct file *file,
136136
unsigned int cmd, unsigned long arg);
137+
#ifdef CONFIG_COMPAT
138+
static int r3964_compat_ioctl(struct tty_struct *tty, struct file *file,
139+
unsigned int cmd, unsigned long arg);
140+
#endif
137141
static void r3964_set_termios(struct tty_struct *tty, struct ktermios *old);
138142
static __poll_t r3964_poll(struct tty_struct *tty, struct file *file,
139143
struct poll_table_struct *wait);
@@ -149,6 +153,9 @@ static struct tty_ldisc_ops tty_ldisc_N_R3964 = {
149153
.read = r3964_read,
150154
.write = r3964_write,
151155
.ioctl = r3964_ioctl,
156+
#ifdef CONFIG_COMPAT
157+
.compat_ioctl = r3964_compat_ioctl,
158+
#endif
152159
.set_termios = r3964_set_termios,
153160
.poll = r3964_poll,
154161
.receive_buf = r3964_receive_buf,
@@ -1210,6 +1217,21 @@ static int r3964_ioctl(struct tty_struct *tty, struct file *file,
12101217
}
12111218
}
12121219

1220+
#ifdef CONFIG_COMPAT
1221+
static int r3964_compat_ioctl(struct tty_struct *tty, struct file *file,
1222+
unsigned int cmd, unsigned long arg)
1223+
{
1224+
switch (cmd) {
1225+
case R3964_ENABLE_SIGNALS:
1226+
case R3964_SETPRIORITY:
1227+
case R3964_USE_BCC:
1228+
return r3964_ioctl(tty, file, cmd, arg);
1229+
default:
1230+
return -ENOIOCTLCMD;
1231+
}
1232+
}
1233+
#endif
1234+
12131235
static void r3964_set_termios(struct tty_struct *tty, struct ktermios *old)
12141236
{
12151237
TRACE_L("set_termios");

drivers/tty/tty_io.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2824,6 +2824,9 @@ static long tty_compat_ioctl(struct file *file, unsigned int cmd,
28242824
return hung_up_tty_compat_ioctl(file, cmd, arg);
28252825
if (ld->ops->compat_ioctl)
28262826
retval = ld->ops->compat_ioctl(tty, file, cmd, arg);
2827+
if (retval == -ENOIOCTLCMD && ld->ops->ioctl)
2828+
retval = ld->ops->ioctl(tty, file,
2829+
(unsigned long)compat_ptr(cmd), arg);
28272830
tty_ldisc_deref(ld);
28282831

28292832
return retval;

include/linux/tty_ldisc.h

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,11 +54,17 @@
5454
* low-level driver can "grab" an ioctl request before the line
5555
* discpline has a chance to see it.
5656
*
57-
* long (*compat_ioctl)(struct tty_struct * tty, struct file * file,
57+
* int (*compat_ioctl)(struct tty_struct * tty, struct file * file,
5858
* unsigned int cmd, unsigned long arg);
5959
*
6060
* Process ioctl calls from 32-bit process on 64-bit system
6161
*
62+
* NOTE: only ioctls that are neither "pointer to compatible
63+
* structure" nor tty-generic. Something private that takes
64+
* an integer or a pointer to wordsize-sensitive structure
65+
* belongs here, but most of ldiscs will happily leave
66+
* it NULL.
67+
*
6268
* void (*set_termios)(struct tty_struct *tty, struct ktermios * old);
6369
*
6470
* This function notifies the line discpline that a change has
@@ -184,7 +190,7 @@ struct tty_ldisc_ops {
184190
const unsigned char *buf, size_t nr);
185191
int (*ioctl)(struct tty_struct *tty, struct file *file,
186192
unsigned int cmd, unsigned long arg);
187-
long (*compat_ioctl)(struct tty_struct *tty, struct file *file,
193+
int (*compat_ioctl)(struct tty_struct *tty, struct file *file,
188194
unsigned int cmd, unsigned long arg);
189195
void (*set_termios)(struct tty_struct *tty, struct ktermios *old);
190196
__poll_t (*poll)(struct tty_struct *, struct file *,

net/nfc/nci/uart.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -465,6 +465,7 @@ static struct tty_ldisc_ops nci_uart_ldisc = {
465465
.receive_buf = nci_uart_tty_receive,
466466
.write_wakeup = nci_uart_tty_wakeup,
467467
.ioctl = nci_uart_tty_ioctl,
468+
.compat_ioctl = nci_uart_tty_ioctl,
468469
};
469470

470471
static int __init nci_uart_init(void)

0 commit comments

Comments
 (0)