aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorArnd Bergmann <arnd@arndb.de>2009-11-10 22:45:22 -0500
committerDavid S. Miller <davem@davemloft.net>2009-11-11 22:22:23 -0500
commit805003a41c035ccbe37d3d5ef5e6df8874346b5a (patch)
tree55828a6642fc6f974842cea3387f2625ec9499b3 /net
parenta2116ed223c88b6c424f42398e54d1607dc785ba (diff)
net/atm: move all compat_ioctl handling to atm/ioctl.c
We have two implementations of the compat_ioctl handling for ATM, the one that we have had for ages in fs/compat_ioctl.c and the one added to net/atm/ioctl.c by David Woodhouse. Unfortunately, both versions are incomplete, and in practice we use a very confusing combination of the two. For ioctl numbers that have the same identifier on 32 and 64 bit systems, we go directly through the compat_ioctl socket operation, for those that differ, we do a conversion in fs/compat_ioctl.c. This patch moves both variants into the vcc_compat_ioctl() function, while preserving the current behaviour. It also kills off the COMPATIBLE_IOCTL definitions that we never use here. Doing it this way is clearly not a good solution, but I hope it is a step into the right direction, so that someone is able to clean up this mess for real. Signed-off-by: Arnd Bergmann <arnd@arndb.de> Cc: Eric Dumazet <eric.dumazet@gmail.com> Cc: David Woodhouse <dwmw2@infradead.org> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
-rw-r--r--net/atm/ioctl.c177
-rw-r--r--net/socket.c218
2 files changed, 175 insertions, 220 deletions
diff --git a/net/atm/ioctl.c b/net/atm/ioctl.c
index 4da8892ced5f..2ea40995dced 100644
--- a/net/atm/ioctl.c
+++ b/net/atm/ioctl.c
@@ -191,8 +191,181 @@ int vcc_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
191} 191}
192 192
193#ifdef CONFIG_COMPAT 193#ifdef CONFIG_COMPAT
194int vcc_compat_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) 194/*
195 * FIXME:
196 * The compat_ioctl handling is duplicated, using both these conversion
197 * routines and the compat argument to the actual handlers. Both
198 * versions are somewhat incomplete and should be merged, e.g. by
199 * moving the ioctl number translation into the actual handlers and
200 * killing the conversion code.
201 *
202 * -arnd, November 2009
203 */
204#define ATM_GETLINKRATE32 _IOW('a', ATMIOC_ITF+1, struct compat_atmif_sioc)
205#define ATM_GETNAMES32 _IOW('a', ATMIOC_ITF+3, struct compat_atm_iobuf)
206#define ATM_GETTYPE32 _IOW('a', ATMIOC_ITF+4, struct compat_atmif_sioc)
207#define ATM_GETESI32 _IOW('a', ATMIOC_ITF+5, struct compat_atmif_sioc)
208#define ATM_GETADDR32 _IOW('a', ATMIOC_ITF+6, struct compat_atmif_sioc)
209#define ATM_RSTADDR32 _IOW('a', ATMIOC_ITF+7, struct compat_atmif_sioc)
210#define ATM_ADDADDR32 _IOW('a', ATMIOC_ITF+8, struct compat_atmif_sioc)
211#define ATM_DELADDR32 _IOW('a', ATMIOC_ITF+9, struct compat_atmif_sioc)
212#define ATM_GETCIRANGE32 _IOW('a', ATMIOC_ITF+10, struct compat_atmif_sioc)
213#define ATM_SETCIRANGE32 _IOW('a', ATMIOC_ITF+11, struct compat_atmif_sioc)
214#define ATM_SETESI32 _IOW('a', ATMIOC_ITF+12, struct compat_atmif_sioc)
215#define ATM_SETESIF32 _IOW('a', ATMIOC_ITF+13, struct compat_atmif_sioc)
216#define ATM_GETSTAT32 _IOW('a', ATMIOC_SARCOM+0, struct compat_atmif_sioc)
217#define ATM_GETSTATZ32 _IOW('a', ATMIOC_SARCOM+1, struct compat_atmif_sioc)
218#define ATM_GETLOOP32 _IOW('a', ATMIOC_SARCOM+2, struct compat_atmif_sioc)
219#define ATM_SETLOOP32 _IOW('a', ATMIOC_SARCOM+3, struct compat_atmif_sioc)
220#define ATM_QUERYLOOP32 _IOW('a', ATMIOC_SARCOM+4, struct compat_atmif_sioc)
221
222static struct {
223 unsigned int cmd32;
224 unsigned int cmd;
225} atm_ioctl_map[] = {
226 { ATM_GETLINKRATE32, ATM_GETLINKRATE },
227 { ATM_GETNAMES32, ATM_GETNAMES },
228 { ATM_GETTYPE32, ATM_GETTYPE },
229 { ATM_GETESI32, ATM_GETESI },
230 { ATM_GETADDR32, ATM_GETADDR },
231 { ATM_RSTADDR32, ATM_RSTADDR },
232 { ATM_ADDADDR32, ATM_ADDADDR },
233 { ATM_DELADDR32, ATM_DELADDR },
234 { ATM_GETCIRANGE32, ATM_GETCIRANGE },
235 { ATM_SETCIRANGE32, ATM_SETCIRANGE },
236 { ATM_SETESI32, ATM_SETESI },
237 { ATM_SETESIF32, ATM_SETESIF },
238 { ATM_GETSTAT32, ATM_GETSTAT },
239 { ATM_GETSTATZ32, ATM_GETSTATZ },
240 { ATM_GETLOOP32, ATM_GETLOOP },
241 { ATM_SETLOOP32, ATM_SETLOOP },
242 { ATM_QUERYLOOP32, ATM_QUERYLOOP },
243};
244
245#define NR_ATM_IOCTL ARRAY_SIZE(atm_ioctl_map)
246
247static int do_atm_iobuf(struct socket *sock, unsigned int cmd,
248 unsigned long arg)
249{
250 struct atm_iobuf __user *iobuf;
251 struct compat_atm_iobuf __user *iobuf32;
252 u32 data;
253 void __user *datap;
254 int len, err;
255
256 iobuf = compat_alloc_user_space(sizeof(*iobuf));
257 iobuf32 = compat_ptr(arg);
258
259 if (get_user(len, &iobuf32->length) ||
260 get_user(data, &iobuf32->buffer))
261 return -EFAULT;
262 datap = compat_ptr(data);
263 if (put_user(len, &iobuf->length) ||
264 put_user(datap, &iobuf->buffer))
265 return -EFAULT;
266
267 err = do_vcc_ioctl(sock, cmd, (unsigned long) iobuf, 0);
268
269 if (!err) {
270 if (copy_in_user(&iobuf32->length, &iobuf->length,
271 sizeof(int)))
272 err = -EFAULT;
273 }
274
275 return err;
276}
277
278static int do_atmif_sioc(struct socket *sock, unsigned int cmd,
279 unsigned long arg)
280{
281 struct atmif_sioc __user *sioc;
282 struct compat_atmif_sioc __user *sioc32;
283 u32 data;
284 void __user *datap;
285 int err;
286
287 sioc = compat_alloc_user_space(sizeof(*sioc));
288 sioc32 = compat_ptr(arg);
289
290 if (copy_in_user(&sioc->number, &sioc32->number, 2 * sizeof(int))
291 || get_user(data, &sioc32->arg))
292 return -EFAULT;
293 datap = compat_ptr(data);
294 if (put_user(datap, &sioc->arg))
295 return -EFAULT;
296
297 err = do_vcc_ioctl(sock, cmd, (unsigned long) sioc, 0);
298
299 if (!err) {
300 if (copy_in_user(&sioc32->length, &sioc->length,
301 sizeof(int)))
302 err = -EFAULT;
303 }
304 return err;
305}
306
307static int do_atm_ioctl(struct socket *sock, unsigned int cmd32,
308 unsigned long arg)
309{
310 int i;
311 unsigned int cmd = 0;
312
313 switch (cmd32) {
314 case SONET_GETSTAT:
315 case SONET_GETSTATZ:
316 case SONET_GETDIAG:
317 case SONET_SETDIAG:
318 case SONET_CLRDIAG:
319 case SONET_SETFRAMING:
320 case SONET_GETFRAMING:
321 case SONET_GETFRSENSE:
322 return do_atmif_sioc(sock, cmd32, arg);
323 }
324
325 for (i = 0; i < NR_ATM_IOCTL; i++) {
326 if (cmd32 == atm_ioctl_map[i].cmd32) {
327 cmd = atm_ioctl_map[i].cmd;
328 break;
329 }
330 }
331 if (i == NR_ATM_IOCTL)
332 return -EINVAL;
333
334 switch (cmd) {
335 case ATM_GETNAMES:
336 return do_atm_iobuf(sock, cmd, arg);
337
338 case ATM_GETLINKRATE:
339 case ATM_GETTYPE:
340 case ATM_GETESI:
341 case ATM_GETADDR:
342 case ATM_RSTADDR:
343 case ATM_ADDADDR:
344 case ATM_DELADDR:
345 case ATM_GETCIRANGE:
346 case ATM_SETCIRANGE:
347 case ATM_SETESI:
348 case ATM_SETESIF:
349 case ATM_GETSTAT:
350 case ATM_GETSTATZ:
351 case ATM_GETLOOP:
352 case ATM_SETLOOP:
353 case ATM_QUERYLOOP:
354 return do_atmif_sioc(sock, cmd, arg);
355 }
356
357 return -EINVAL;
358}
359
360int vcc_compat_ioctl(struct socket *sock, unsigned int cmd,
361 unsigned long arg)
195{ 362{
196 return do_vcc_ioctl(sock, cmd, arg, 1); 363 int ret;
364
365 ret = do_vcc_ioctl(sock, cmd, arg, 1);
366 if (ret != -ENOIOCTLCMD)
367 return ret;
368
369 return do_atm_ioctl(sock, cmd, arg);
197} 370}
198#endif 371#endif
diff --git a/net/socket.c b/net/socket.c
index 05c482848a67..402abb39cbfe 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -100,14 +100,6 @@
100#include <linux/if_tun.h> 100#include <linux/if_tun.h>
101#include <linux/ipv6_route.h> 101#include <linux/ipv6_route.h>
102#include <linux/route.h> 102#include <linux/route.h>
103#include <linux/atmdev.h>
104#include <linux/atmarp.h>
105#include <linux/atmsvc.h>
106#include <linux/atmlec.h>
107#include <linux/atmclip.h>
108#include <linux/atmmpc.h>
109#include <linux/atm_tcp.h>
110#include <linux/sonet.h>
111#include <linux/sockios.h> 103#include <linux/sockios.h>
112#include <linux/atalk.h> 104#include <linux/atalk.h>
113 105
@@ -2917,173 +2909,6 @@ static int old_bridge_ioctl(compat_ulong_t __user *argp)
2917 return -EINVAL; 2909 return -EINVAL;
2918} 2910}
2919 2911
2920struct atmif_sioc32 {
2921 compat_int_t number;
2922 compat_int_t length;
2923 compat_caddr_t arg;
2924};
2925
2926struct atm_iobuf32 {
2927 compat_int_t length;
2928 compat_caddr_t buffer;
2929};
2930
2931#define ATM_GETLINKRATE32 _IOW('a', ATMIOC_ITF+1, struct atmif_sioc32)
2932#define ATM_GETNAMES32 _IOW('a', ATMIOC_ITF+3, struct atm_iobuf32)
2933#define ATM_GETTYPE32 _IOW('a', ATMIOC_ITF+4, struct atmif_sioc32)
2934#define ATM_GETESI32 _IOW('a', ATMIOC_ITF+5, struct atmif_sioc32)
2935#define ATM_GETADDR32 _IOW('a', ATMIOC_ITF+6, struct atmif_sioc32)
2936#define ATM_RSTADDR32 _IOW('a', ATMIOC_ITF+7, struct atmif_sioc32)
2937#define ATM_ADDADDR32 _IOW('a', ATMIOC_ITF+8, struct atmif_sioc32)
2938#define ATM_DELADDR32 _IOW('a', ATMIOC_ITF+9, struct atmif_sioc32)
2939#define ATM_GETCIRANGE32 _IOW('a', ATMIOC_ITF+10, struct atmif_sioc32)
2940#define ATM_SETCIRANGE32 _IOW('a', ATMIOC_ITF+11, struct atmif_sioc32)
2941#define ATM_SETESI32 _IOW('a', ATMIOC_ITF+12, struct atmif_sioc32)
2942#define ATM_SETESIF32 _IOW('a', ATMIOC_ITF+13, struct atmif_sioc32)
2943#define ATM_GETSTAT32 _IOW('a', ATMIOC_SARCOM+0, struct atmif_sioc32)
2944#define ATM_GETSTATZ32 _IOW('a', ATMIOC_SARCOM+1, struct atmif_sioc32)
2945#define ATM_GETLOOP32 _IOW('a', ATMIOC_SARCOM+2, struct atmif_sioc32)
2946#define ATM_SETLOOP32 _IOW('a', ATMIOC_SARCOM+3, struct atmif_sioc32)
2947#define ATM_QUERYLOOP32 _IOW('a', ATMIOC_SARCOM+4, struct atmif_sioc32)
2948
2949static struct {
2950 unsigned int cmd32;
2951 unsigned int cmd;
2952} atm_ioctl_map[] = {
2953 { ATM_GETLINKRATE32, ATM_GETLINKRATE },
2954 { ATM_GETNAMES32, ATM_GETNAMES },
2955 { ATM_GETTYPE32, ATM_GETTYPE },
2956 { ATM_GETESI32, ATM_GETESI },
2957 { ATM_GETADDR32, ATM_GETADDR },
2958 { ATM_RSTADDR32, ATM_RSTADDR },
2959 { ATM_ADDADDR32, ATM_ADDADDR },
2960 { ATM_DELADDR32, ATM_DELADDR },
2961 { ATM_GETCIRANGE32, ATM_GETCIRANGE },
2962 { ATM_SETCIRANGE32, ATM_SETCIRANGE },
2963 { ATM_SETESI32, ATM_SETESI },
2964 { ATM_SETESIF32, ATM_SETESIF },
2965 { ATM_GETSTAT32, ATM_GETSTAT },
2966 { ATM_GETSTATZ32, ATM_GETSTATZ },
2967 { ATM_GETLOOP32, ATM_GETLOOP },
2968 { ATM_SETLOOP32, ATM_SETLOOP },
2969 { ATM_QUERYLOOP32, ATM_QUERYLOOP }
2970};
2971
2972#define NR_ATM_IOCTL ARRAY_SIZE(atm_ioctl_map)
2973
2974static int do_atm_iobuf(struct net *net, struct socket *sock,
2975 unsigned int cmd, unsigned long arg)
2976{
2977 struct atm_iobuf __user *iobuf;
2978 struct atm_iobuf32 __user *iobuf32;
2979 u32 data;
2980 void __user *datap;
2981 int len, err;
2982
2983 iobuf = compat_alloc_user_space(sizeof(*iobuf));
2984 iobuf32 = compat_ptr(arg);
2985
2986 if (get_user(len, &iobuf32->length) ||
2987 get_user(data, &iobuf32->buffer))
2988 return -EFAULT;
2989 datap = compat_ptr(data);
2990 if (put_user(len, &iobuf->length) ||
2991 put_user(datap, &iobuf->buffer))
2992 return -EFAULT;
2993
2994 err = sock_do_ioctl(net, sock, cmd, (unsigned long)iobuf);
2995
2996 if (!err) {
2997 if (copy_in_user(&iobuf32->length, &iobuf->length,
2998 sizeof(int)))
2999 err = -EFAULT;
3000 }
3001
3002 return err;
3003}
3004
3005static int do_atmif_sioc(struct net *net, struct socket *sock,
3006 unsigned int cmd, unsigned long arg)
3007{
3008 struct atmif_sioc __user *sioc;
3009 struct atmif_sioc32 __user *sioc32;
3010 u32 data;
3011 void __user *datap;
3012 int err;
3013
3014 sioc = compat_alloc_user_space(sizeof(*sioc));
3015 sioc32 = compat_ptr(arg);
3016
3017 if (copy_in_user(&sioc->number, &sioc32->number, 2 * sizeof(int)) ||
3018 get_user(data, &sioc32->arg))
3019 return -EFAULT;
3020 datap = compat_ptr(data);
3021 if (put_user(datap, &sioc->arg))
3022 return -EFAULT;
3023
3024 err = sock_do_ioctl(net, sock, cmd, (unsigned long) sioc);
3025
3026 if (!err) {
3027 if (copy_in_user(&sioc32->length, &sioc->length,
3028 sizeof(int)))
3029 err = -EFAULT;
3030 }
3031 return err;
3032}
3033
3034static int do_atm_ioctl(struct net *net, struct socket *sock,
3035 unsigned int cmd32, unsigned long arg)
3036{
3037 int i;
3038 unsigned int cmd = 0;
3039
3040 switch (cmd32) {
3041 case SONET_GETSTAT:
3042 case SONET_GETSTATZ:
3043 case SONET_GETDIAG:
3044 case SONET_SETDIAG:
3045 case SONET_CLRDIAG:
3046 case SONET_SETFRAMING:
3047 case SONET_GETFRAMING:
3048 case SONET_GETFRSENSE:
3049 return do_atmif_sioc(net, sock, cmd32, arg);
3050 }
3051
3052 for (i = 0; i < NR_ATM_IOCTL; i++) {
3053 if (cmd32 == atm_ioctl_map[i].cmd32) {
3054 cmd = atm_ioctl_map[i].cmd;
3055 break;
3056 }
3057 }
3058 if (i == NR_ATM_IOCTL)
3059 return -EINVAL;
3060
3061 switch (cmd) {
3062 case ATM_GETNAMES:
3063 return do_atm_iobuf(net, sock, cmd, arg);
3064
3065 case ATM_GETLINKRATE:
3066 case ATM_GETTYPE:
3067 case ATM_GETESI:
3068 case ATM_GETADDR:
3069 case ATM_RSTADDR:
3070 case ATM_ADDADDR:
3071 case ATM_DELADDR:
3072 case ATM_GETCIRANGE:
3073 case ATM_SETCIRANGE:
3074 case ATM_SETESI:
3075 case ATM_SETESIF:
3076 case ATM_GETSTAT:
3077 case ATM_GETSTATZ:
3078 case ATM_GETLOOP:
3079 case ATM_SETLOOP:
3080 case ATM_QUERYLOOP:
3081 return do_atmif_sioc(net, sock, cmd, arg);
3082 }
3083
3084 return -EINVAL;
3085}
3086
3087static int compat_sock_ioctl_trans(struct file *file, struct socket *sock, 2912static int compat_sock_ioctl_trans(struct file *file, struct socket *sock,
3088 unsigned int cmd, unsigned long arg) 2913 unsigned int cmd, unsigned long arg)
3089{ 2914{
@@ -3173,49 +2998,6 @@ static int compat_sock_ioctl_trans(struct file *file, struct socket *sock,
3173 case SIOCSMIIREG: 2998 case SIOCSMIIREG:
3174 return dev_ifsioc(net, sock, cmd, argp); 2999 return dev_ifsioc(net, sock, cmd, argp);
3175 3000
3176 case ATM_GETLINKRATE32:
3177 case ATM_GETNAMES32:
3178 case ATM_GETTYPE32:
3179 case ATM_GETESI32:
3180 case ATM_GETADDR32:
3181 case ATM_RSTADDR32:
3182 case ATM_ADDADDR32:
3183 case ATM_DELADDR32:
3184 case ATM_GETCIRANGE32:
3185 case ATM_SETCIRANGE32:
3186 case ATM_SETESI32:
3187 case ATM_SETESIF32:
3188 case ATM_GETSTAT32:
3189 case ATM_GETSTATZ32:
3190 case ATM_GETLOOP32:
3191 case ATM_SETLOOP32:
3192 case ATM_QUERYLOOP32:
3193 case SONET_GETSTAT:
3194 case SONET_GETSTATZ:
3195 case SONET_GETDIAG:
3196 case SONET_SETDIAG:
3197 case SONET_CLRDIAG:
3198 case SONET_SETFRAMING:
3199 case SONET_GETFRAMING:
3200 case SONET_GETFRSENSE:
3201 return do_atm_ioctl(net, sock, cmd, arg);
3202
3203 case ATMSIGD_CTRL:
3204 case ATMARPD_CTRL:
3205 case ATMLEC_CTRL:
3206 case ATMLEC_MCAST:
3207 case ATMLEC_DATA:
3208 case ATM_SETSC:
3209 case SIOCSIFATMTCP:
3210 case SIOCMKCLIP:
3211 case ATMARP_MKIP:
3212 case ATMARP_SETENTRY:
3213 case ATMARP_ENCAP:
3214 case ATMTCP_CREATE:
3215 case ATMTCP_REMOVE:
3216 case ATMMPC_CTRL:
3217 case ATMMPC_DATA:
3218
3219 case SIOCSARP: 3001 case SIOCSARP:
3220 case SIOCGARP: 3002 case SIOCGARP:
3221 case SIOCDARP: 3003 case SIOCDARP: