• Mike Frysinger's avatar
    x32: Use compat shims for {g,s}etsockopt · 515c7af8
    Mike Frysinger authored
    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/423649Reported-by: default avatarMads <mads@ab3.no>
    Signed-off-by: default avatarMike 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: default avatarH. Peter Anvin <hpa@zytor.com>
    515c7af8
syscall_64.tbl 12 KB