diff options
author | David Woodhouse <David.Woodhouse@intel.com> | 2008-12-04 01:12:38 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2008-12-04 01:12:38 -0500 |
commit | 8865c418caf4e9dd2c24bdfae3a5a4106e143e60 (patch) | |
tree | 4d7fac2c74af56c6aaf83b324b349b76c5f949d9 /net/atm/ioctl.c | |
parent | dcd39c90290297f6e6ed8a04bb20da7ac2b043c5 (diff) |
atm: 32-bit ioctl compatibility
We lack compat ioctl support through most of the ATM code. This patch
deals with most of it, and I can now at least use BR2684 and PPPoATM
with 32-bit userspace.
I haven't added a .compat_ioctl method to struct atm_ioctl, because
AFAICT none of the current users need any conversion -- so we can just
call the ->ioctl() method in every case. I looked at br2684, clip, lec,
mpc, pppoatm and atmtcp.
In svc_compat_ioctl() the only mangling which is needed is to change
COMPAT_ATM_ADDPARTY to ATM_ADDPARTY. Although it's defined as
_IOW('a', ATMIOC_SPECIAL+4,struct atm_iobuf)
it doesn't actually _take_ a struct atm_iobuf as an argument -- it takes
a struct sockaddr_atmsvc, which _is_ the same between 32-bit and 64-bit
code, so doesn't need conversion.
Almost all of vcc_ioctl() would have been identical, so I converted that
into a core do_vcc_ioctl() function with an 'int compat' argument.
I've done the same with atm_dev_ioctl(), where there _are_ a few
differences, but still it's relatively contained and there would
otherwise have been a lot of duplication.
I haven't done any of the actual device-specific ioctls, although I've
added a compat_ioctl method to struct atmdev_ops.
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/atm/ioctl.c')
-rw-r--r-- | net/atm/ioctl.c | 49 |
1 files changed, 43 insertions, 6 deletions
diff --git a/net/atm/ioctl.c b/net/atm/ioctl.c index 7afd8e7754fd..76ed3c8d26e6 100644 --- a/net/atm/ioctl.c +++ b/net/atm/ioctl.c | |||
@@ -19,6 +19,7 @@ | |||
19 | #include <linux/atmlec.h> | 19 | #include <linux/atmlec.h> |
20 | #include <linux/mutex.h> | 20 | #include <linux/mutex.h> |
21 | #include <asm/ioctls.h> | 21 | #include <asm/ioctls.h> |
22 | #include <net/compat.h> | ||
22 | 23 | ||
23 | #include "resources.h" | 24 | #include "resources.h" |
24 | #include "signaling.h" /* for WAITING and sigd_attach */ | 25 | #include "signaling.h" /* for WAITING and sigd_attach */ |
@@ -46,7 +47,7 @@ void deregister_atm_ioctl(struct atm_ioctl *ioctl) | |||
46 | EXPORT_SYMBOL(register_atm_ioctl); | 47 | EXPORT_SYMBOL(register_atm_ioctl); |
47 | EXPORT_SYMBOL(deregister_atm_ioctl); | 48 | EXPORT_SYMBOL(deregister_atm_ioctl); |
48 | 49 | ||
49 | int vcc_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) | 50 | static int do_vcc_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg, int compat) |
50 | { | 51 | { |
51 | struct sock *sk = sock->sk; | 52 | struct sock *sk = sock->sk; |
52 | struct atm_vcc *vcc; | 53 | struct atm_vcc *vcc; |
@@ -80,13 +81,25 @@ int vcc_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) | |||
80 | goto done; | 81 | goto done; |
81 | } | 82 | } |
82 | case SIOCGSTAMP: /* borrowed from IP */ | 83 | case SIOCGSTAMP: /* borrowed from IP */ |
83 | error = sock_get_timestamp(sk, argp); | 84 | #ifdef CONFIG_COMPAT |
85 | if (compat) | ||
86 | error = compat_sock_get_timestamp(sk, argp); | ||
87 | else | ||
88 | #endif | ||
89 | error = sock_get_timestamp(sk, argp); | ||
84 | goto done; | 90 | goto done; |
85 | case SIOCGSTAMPNS: /* borrowed from IP */ | 91 | case SIOCGSTAMPNS: /* borrowed from IP */ |
86 | error = sock_get_timestampns(sk, argp); | 92 | #ifdef CONFIG_COMPAT |
93 | if (compat) | ||
94 | error = compat_sock_get_timestampns(sk, argp); | ||
95 | else | ||
96 | #endif | ||
97 | error = sock_get_timestampns(sk, argp); | ||
87 | goto done; | 98 | goto done; |
88 | case ATM_SETSC: | 99 | case ATM_SETSC: |
89 | printk(KERN_WARNING "ATM_SETSC is obsolete\n"); | 100 | if (net_ratelimit()) |
101 | printk(KERN_WARNING "ATM_SETSC is obsolete; used by %s:%d\n", | ||
102 | current->comm, task_pid_nr(current)); | ||
90 | error = 0; | 103 | error = 0; |
91 | goto done; | 104 | goto done; |
92 | case ATMSIGD_CTRL: | 105 | case ATMSIGD_CTRL: |
@@ -99,12 +112,23 @@ int vcc_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) | |||
99 | * info uses kernel pointers as opaque references, | 112 | * info uses kernel pointers as opaque references, |
100 | * so the holder of the file descriptor can scribble | 113 | * so the holder of the file descriptor can scribble |
101 | * on the kernel... so we should make sure that we | 114 | * on the kernel... so we should make sure that we |
102 | * have the same privledges that /proc/kcore needs | 115 | * have the same privileges that /proc/kcore needs |
103 | */ | 116 | */ |
104 | if (!capable(CAP_SYS_RAWIO)) { | 117 | if (!capable(CAP_SYS_RAWIO)) { |
105 | error = -EPERM; | 118 | error = -EPERM; |
106 | goto done; | 119 | goto done; |
107 | } | 120 | } |
121 | #ifdef CONFIG_COMPAT | ||
122 | /* WTF? I don't even want to _think_ about making this | ||
123 | work for 32-bit userspace. TBH I don't really want | ||
124 | to think about it at all. dwmw2. */ | ||
125 | if (compat) { | ||
126 | if (net_ratelimit()) | ||
127 | printk(KERN_WARNING "32-bit task cannot be atmsigd\n"); | ||
128 | error = -EINVAL; | ||
129 | goto done; | ||
130 | } | ||
131 | #endif | ||
108 | error = sigd_attach(vcc); | 132 | error = sigd_attach(vcc); |
109 | if (!error) | 133 | if (!error) |
110 | sock->state = SS_CONNECTED; | 134 | sock->state = SS_CONNECTED; |
@@ -155,8 +179,21 @@ int vcc_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) | |||
155 | if (error != -ENOIOCTLCMD) | 179 | if (error != -ENOIOCTLCMD) |
156 | goto done; | 180 | goto done; |
157 | 181 | ||
158 | error = atm_dev_ioctl(cmd, argp); | 182 | error = atm_dev_ioctl(cmd, argp, compat); |
159 | 183 | ||
160 | done: | 184 | done: |
161 | return error; | 185 | return error; |
162 | } | 186 | } |
187 | |||
188 | |||
189 | int vcc_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) | ||
190 | { | ||
191 | return do_vcc_ioctl(sock, cmd, arg, 0); | ||
192 | } | ||
193 | |||
194 | #ifdef CONFIG_COMPAT | ||
195 | int vcc_compat_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) | ||
196 | { | ||
197 | return do_vcc_ioctl(sock, cmd, arg, 1); | ||
198 | } | ||
199 | #endif | ||