aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm
diff options
context:
space:
mode:
authorNicolas Pitre <nico@cam.org>2006-02-08 16:19:36 -0500
committerRussell King <rmk+kernel@arm.linux.org.uk>2006-02-08 16:19:36 -0500
commit99595d0237926b5aba1fe4c844a011a1ba1ee1f8 (patch)
treea879592fe82042e78304919532aeaa89fcf98ce5 /arch/arm
parenta73a3ff127df1b35d6771f7d3ce36373def8398f (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>
Diffstat (limited to 'arch/arm')
-rw-r--r--arch/arm/kernel/calls.S8
-rw-r--r--arch/arm/kernel/sys_oabi-compat.c71
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
352asmlinkage 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
362asmlinkage 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
372asmlinkage 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
385asmlinkage 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