aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/syscalls
diff options
context:
space:
mode:
authorMike Frysinger <vapier@gentoo.org>2012-08-18 16:11:37 -0400
committerH. Peter Anvin <hpa@zytor.com>2012-08-18 17:15:39 -0400
commit515c7af85ed92696c311c53d53cb4898ff32d784 (patch)
tree2353722cf4b13c722157cf9347430789c5255408 /arch/x86/syscalls
parentf026cfa82f628db24b8cea41b9d6202af104cecb (diff)
x32: Use compat shims for {g,s}etsockopt
Some of the arguments to {g,s}etsockopt are passed in userland pointers. If we try to use the 64bit entry point, we end up sometimes failing. For example, dhcpcd doesn't run in x32: # dhcpcd eth0 dhcpcd[1979]: version 5.5.6 starting dhcpcd[1979]: eth0: broadcasting for a lease dhcpcd[1979]: eth0: open_socket: Invalid argument dhcpcd[1979]: eth0: send_raw_packet: Bad file descriptor The code in particular is getting back EINVAL when doing: struct sock_fprog pf; setsockopt(s, SOL_SOCKET, SO_ATTACH_FILTER, &pf, sizeof(pf)); Diving into the kernel code, we can see: include/linux/filter.h: struct sock_fprog { unsigned short len; struct sock_filter __user *filter; }; net/core/sock.c: case SO_ATTACH_FILTER: ret = -EINVAL; if (optlen == sizeof(struct sock_fprog)) { struct sock_fprog fprog; ret = -EFAULT; if (copy_from_user(&fprog, optval, sizeof(fprog))) break; ret = sk_attach_filter(&fprog, sk); } break; arch/x86/syscalls/syscall_64.tbl: 54 common setsockopt sys_setsockopt 55 common getsockopt sys_getsockopt So for x64, sizeof(sock_fprog) is 16 bytes. For x86/x32, it's 8 bytes. This comes down to the pointer being 32bit for x32, which means we need to do structure size translation. But since x32 comes in directly to sys_setsockopt, it doesn't get translated like x86. After changing the syscall table and rebuilding glibc with the new kernel headers, dhcp runs fine in an x32 userland. Oddly, it seems like Linus noted the same thing during the initial port, but I guess that was missed/lost along the way: https://lkml.org/lkml/2011/8/26/452 [ hpa: tagging for -stable since this is an ABI fix. ] Bugzilla: https://bugs.gentoo.org/423649 Reported-by: Mads <mads@ab3.no> Signed-off-by: Mike Frysinger <vapier@gentoo.org> Link: http://lkml.kernel.org/r/1345320697-15713-1-git-send-email-vapier@gentoo.org Cc: H. J. Lu <hjl.tools@gmail.com> Cc: <stable@vger.kernel.org> v3.4..v3.5 Signed-off-by: H. Peter Anvin <hpa@zytor.com>
Diffstat (limited to 'arch/x86/syscalls')
-rw-r--r--arch/x86/syscalls/syscall_64.tbl6
1 files changed, 4 insertions, 2 deletions
diff --git a/arch/x86/syscalls/syscall_64.tbl b/arch/x86/syscalls/syscall_64.tbl
index 29aed7ac2c02..a582bfed95bb 100644
--- a/arch/x86/syscalls/syscall_64.tbl
+++ b/arch/x86/syscalls/syscall_64.tbl
@@ -60,8 +60,8 @@
6051 common getsockname sys_getsockname 6051 common getsockname sys_getsockname
6152 common getpeername sys_getpeername 6152 common getpeername sys_getpeername
6253 common socketpair sys_socketpair 6253 common socketpair sys_socketpair
6354 common setsockopt sys_setsockopt 6354 64 setsockopt sys_setsockopt
6455 common getsockopt sys_getsockopt 6455 64 getsockopt sys_getsockopt
6556 common clone stub_clone 6556 common clone stub_clone
6657 common fork stub_fork 6657 common fork stub_fork
6758 common vfork stub_vfork 6758 common vfork stub_vfork
@@ -353,3 +353,5 @@
353538 x32 sendmmsg compat_sys_sendmmsg 353538 x32 sendmmsg compat_sys_sendmmsg
354539 x32 process_vm_readv compat_sys_process_vm_readv 354539 x32 process_vm_readv compat_sys_process_vm_readv
355540 x32 process_vm_writev compat_sys_process_vm_writev 355540 x32 process_vm_writev compat_sys_process_vm_writev
356541 x32 setsockopt compat_sys_setsockopt
357542 x32 getsockopt compat_sys_getsockopt