diff options
author | Nicolas Pitre <nico@cam.org> | 2006-02-08 16:19:36 -0500 |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2006-02-08 16:19:36 -0500 |
commit | 99595d0237926b5aba1fe4c844a011a1ba1ee1f8 (patch) | |
tree | a879592fe82042e78304919532aeaa89fcf98ce5 | |
parent | a73a3ff127df1b35d6771f7d3ce36373def8398f (diff) |
[ARM] 3308/1: old ABI compat: struct sockaddr_un
Patch from Nicolas Pitre
struct sockaddr_un loses its padding with EABI. Since the size of the
structure is used as a validation test in unix_mkname(), we need to
change the length argument to 110 whenever it is 112.
Signed-off-by: Nicolas Pitre <nico@cam.org>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
-rw-r--r-- | arch/arm/kernel/calls.S | 8 | ||||
-rw-r--r-- | arch/arm/kernel/sys_oabi-compat.c | 71 |
2 files changed, 75 insertions, 4 deletions
diff --git a/arch/arm/kernel/calls.S b/arch/arm/kernel/calls.S index d058e7c12568..8c3035d5ffc9 100644 --- a/arch/arm/kernel/calls.S +++ b/arch/arm/kernel/calls.S | |||
@@ -291,21 +291,21 @@ | |||
291 | CALL(sys_mq_getsetattr) | 291 | CALL(sys_mq_getsetattr) |
292 | /* 280 */ CALL(sys_waitid) | 292 | /* 280 */ CALL(sys_waitid) |
293 | CALL(sys_socket) | 293 | CALL(sys_socket) |
294 | CALL(sys_bind) | 294 | CALL(ABI(sys_bind, sys_oabi_bind)) |
295 | CALL(sys_connect) | 295 | CALL(ABI(sys_connect, sys_oabi_connect)) |
296 | CALL(sys_listen) | 296 | CALL(sys_listen) |
297 | /* 285 */ CALL(sys_accept) | 297 | /* 285 */ CALL(sys_accept) |
298 | CALL(sys_getsockname) | 298 | CALL(sys_getsockname) |
299 | CALL(sys_getpeername) | 299 | CALL(sys_getpeername) |
300 | CALL(sys_socketpair) | 300 | CALL(sys_socketpair) |
301 | CALL(sys_send) | 301 | CALL(sys_send) |
302 | /* 290 */ CALL(sys_sendto) | 302 | /* 290 */ CALL(ABI(sys_sendto, sys_oabi_sendto)) |
303 | CALL(sys_recv) | 303 | CALL(sys_recv) |
304 | CALL(sys_recvfrom) | 304 | CALL(sys_recvfrom) |
305 | CALL(sys_shutdown) | 305 | CALL(sys_shutdown) |
306 | CALL(sys_setsockopt) | 306 | CALL(sys_setsockopt) |
307 | /* 295 */ CALL(sys_getsockopt) | 307 | /* 295 */ CALL(sys_getsockopt) |
308 | CALL(sys_sendmsg) | 308 | CALL(ABI(sys_sendmsg, sys_oabi_sendmsg)) |
309 | CALL(sys_recvmsg) | 309 | CALL(sys_recvmsg) |
310 | CALL(ABI(sys_semop, sys_oabi_semop)) | 310 | CALL(ABI(sys_semop, sys_oabi_semop)) |
311 | CALL(sys_semget) | 311 | CALL(sys_semget) |
diff --git a/arch/arm/kernel/sys_oabi-compat.c b/arch/arm/kernel/sys_oabi-compat.c index eafa8e5284af..9d4b76409c64 100644 --- a/arch/arm/kernel/sys_oabi-compat.c +++ b/arch/arm/kernel/sys_oabi-compat.c | |||
@@ -59,6 +59,16 @@ | |||
59 | * struct sembuf loses its padding with EABI. Since arrays of them are | 59 | * struct sembuf loses its padding with EABI. Since arrays of them are |
60 | * used they have to be copyed to remove the padding. Compatibility wrappers | 60 | * used they have to be copyed to remove the padding. Compatibility wrappers |
61 | * provided below. | 61 | * provided below. |
62 | * | ||
63 | * sys_bind: | ||
64 | * sys_connect: | ||
65 | * sys_sendmsg: | ||
66 | * sys_sendto: | ||
67 | * | ||
68 | * struct sockaddr_un loses its padding with EABI. Since the size of the | ||
69 | * structure is used as a validation test in unix_mkname(), we need to | ||
70 | * change the length argument to 110 whenever it is 112. Compatibility | ||
71 | * wrappers provided below. | ||
62 | */ | 72 | */ |
63 | 73 | ||
64 | #include <linux/syscalls.h> | 74 | #include <linux/syscalls.h> |
@@ -67,6 +77,7 @@ | |||
67 | #include <linux/fcntl.h> | 77 | #include <linux/fcntl.h> |
68 | #include <linux/eventpoll.h> | 78 | #include <linux/eventpoll.h> |
69 | #include <linux/sem.h> | 79 | #include <linux/sem.h> |
80 | #include <linux/socket.h> | ||
70 | #include <asm/ipc.h> | 81 | #include <asm/ipc.h> |
71 | #include <asm/uaccess.h> | 82 | #include <asm/uaccess.h> |
72 | 83 | ||
@@ -337,3 +348,63 @@ asmlinkage int sys_oabi_ipc(uint call, int first, int second, int third, | |||
337 | return sys_ipc(call, first, second, third, ptr, fifth); | 348 | return sys_ipc(call, first, second, third, ptr, fifth); |
338 | } | 349 | } |
339 | } | 350 | } |
351 | |||
352 | asmlinkage long sys_oabi_bind(int fd, struct sockaddr __user *addr, int addrlen) | ||
353 | { | ||
354 | sa_family_t sa_family; | ||
355 | if (addrlen == 112 && | ||
356 | get_user(sa_family, &addr->sa_family) == 0 && | ||
357 | sa_family == AF_UNIX) | ||
358 | addrlen = 110; | ||
359 | return sys_bind(fd, addr, addrlen); | ||
360 | } | ||
361 | |||
362 | asmlinkage long sys_oabi_connect(int fd, struct sockaddr __user *addr, int addrlen) | ||
363 | { | ||
364 | sa_family_t sa_family; | ||
365 | if (addrlen == 112 && | ||
366 | get_user(sa_family, &addr->sa_family) == 0 && | ||
367 | sa_family == AF_UNIX) | ||
368 | addrlen = 110; | ||
369 | return sys_connect(fd, addr, addrlen); | ||
370 | } | ||
371 | |||
372 | asmlinkage long sys_oabi_sendto(int fd, void __user *buff, | ||
373 | size_t len, unsigned flags, | ||
374 | struct sockaddr __user *addr, | ||
375 | int addrlen) | ||
376 | { | ||
377 | sa_family_t sa_family; | ||
378 | if (addrlen == 112 && | ||
379 | get_user(sa_family, &addr->sa_family) == 0 && | ||
380 | sa_family == AF_UNIX) | ||
381 | addrlen = 110; | ||
382 | return sys_sendto(fd, buff, len, flags, addr, addrlen); | ||
383 | } | ||
384 | |||
385 | asmlinkage long sys_oabi_sendmsg(int fd, struct msghdr __user *msg, unsigned flags) | ||
386 | { | ||
387 | struct sockaddr __user *addr; | ||
388 | int msg_namelen; | ||
389 | sa_family_t sa_family; | ||
390 | if (msg && | ||
391 | get_user(msg_namelen, &msg->msg_namelen) == 0 && | ||
392 | msg_namelen == 112 && | ||
393 | get_user(addr, &msg->msg_name) == 0 && | ||
394 | get_user(sa_family, &addr->sa_family) == 0 && | ||
395 | sa_family == AF_UNIX) | ||
396 | { | ||
397 | /* | ||
398 | * HACK ALERT: there is a limit to how much backward bending | ||
399 | * we should do for what is actually a transitional | ||
400 | * compatibility layer. This already has known flaws with | ||
401 | * a few ioctls that we don't intend to fix. Therefore | ||
402 | * consider this blatent hack as another one... and take care | ||
403 | * to run for cover. In most cases it will "just work fine". | ||
404 | * If it doesn't, well, tough. | ||
405 | */ | ||
406 | put_user(110, &msg->msg_namelen); | ||
407 | } | ||
408 | return sys_sendmsg(fd, msg, flags); | ||
409 | } | ||
410 | |||