summary refs log tree commit diff
path: root/arch/arm/kernel/sys_oabi-compat.c
diff options
context:
space:
mode:
authorNicolas Pitre <nico@cam.org>2006-02-08 21:19:36 +0000
committerRussell King <rmk+kernel@arm.linux.org.uk>2006-02-08 21:19:36 +0000
commit99595d0237926b5aba1fe4c844a011a1ba1ee1f8 (patch)
treea879592fe82042e78304919532aeaa89fcf98ce5 /arch/arm/kernel/sys_oabi-compat.c
parenta73a3ff127df1b35d6771f7d3ce36373def8398f (diff)
downloadlinux-99595d0237926b5aba1fe4c844a011a1ba1ee1f8.tar.gz
[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/kernel/sys_oabi-compat.c')
-rw-r--r--arch/arm/kernel/sys_oabi-compat.c71
1 files changed, 71 insertions, 0 deletions
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 @@
  *   struct sembuf loses its padding with EABI.  Since arrays of them are
  *   used they have to be copyed to remove the padding. Compatibility wrappers
  *   provided below.
+ *
+ * sys_bind:
+ * sys_connect:
+ * sys_sendmsg:
+ * sys_sendto:
+ *
+ *   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.  Compatibility
+ *   wrappers provided below.
  */
 
 #include <linux/syscalls.h>
@@ -67,6 +77,7 @@
 #include <linux/fcntl.h>
 #include <linux/eventpoll.h>
 #include <linux/sem.h>
+#include <linux/socket.h>
 #include <asm/ipc.h>
 #include <asm/uaccess.h>
 
@@ -337,3 +348,63 @@ asmlinkage int sys_oabi_ipc(uint call, int first, int second, int third,
 		return sys_ipc(call, first, second, third, ptr, fifth);
 	}
 }
+
+asmlinkage long sys_oabi_bind(int fd, struct sockaddr __user *addr, int addrlen)
+{
+	sa_family_t sa_family;
+	if (addrlen == 112 &&
+	    get_user(sa_family, &addr->sa_family) == 0 &&
+	    sa_family == AF_UNIX)
+			addrlen = 110;
+	return sys_bind(fd, addr, addrlen);
+}
+
+asmlinkage long sys_oabi_connect(int fd, struct sockaddr __user *addr, int addrlen)
+{
+	sa_family_t sa_family;
+	if (addrlen == 112 &&
+	    get_user(sa_family, &addr->sa_family) == 0 &&
+	    sa_family == AF_UNIX)
+			addrlen = 110;
+	return sys_connect(fd, addr, addrlen);
+}
+
+asmlinkage long sys_oabi_sendto(int fd, void __user *buff,
+				size_t len, unsigned flags,
+				struct sockaddr __user *addr,
+				int addrlen)
+{
+	sa_family_t sa_family;
+	if (addrlen == 112 &&
+	    get_user(sa_family, &addr->sa_family) == 0 &&
+	    sa_family == AF_UNIX)
+			addrlen = 110;
+	return sys_sendto(fd, buff, len, flags, addr, addrlen);
+}
+
+asmlinkage long sys_oabi_sendmsg(int fd, struct msghdr __user *msg, unsigned flags)
+{
+	struct sockaddr __user *addr;
+	int msg_namelen;
+	sa_family_t sa_family;
+	if (msg &&
+	    get_user(msg_namelen, &msg->msg_namelen) == 0 &&
+	    msg_namelen == 112 &&
+	    get_user(addr, &msg->msg_name) == 0 &&
+	    get_user(sa_family, &addr->sa_family) == 0 &&
+	    sa_family == AF_UNIX)
+	{
+		/*
+		 * HACK ALERT: there is a limit to how much backward bending
+		 * we should do for what is actually a transitional
+		 * compatibility layer.  This already has known flaws with
+		 * a few ioctls that we don't intend to fix.  Therefore
+		 * consider this blatent hack as another one... and take care
+		 * to run for cover.  In most cases it will "just work fine".
+		 * If it doesn't, well, tough.
+		 */
+		put_user(110, &msg->msg_namelen);
+	}
+	return sys_sendmsg(fd, msg, flags);
+}
+