Date: Mon, 07 Jan 2019 23:16:47 +0000 From: bugzilla-noreply@freebsd.org To: bugs@FreeBSD.org Subject: [Bug 234722] [patch] [linux] getsockopt(SOL_SOCKET, SO_PEERCRED) on a Unix socket fails silently Message-ID: <bug-234722-227@https.bugs.freebsd.org/bugzilla/>
next in thread | raw e-mail | index | archive | help
https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=234722 Bug ID: 234722 Summary: [patch] [linux] getsockopt(SOL_SOCKET, SO_PEERCRED) on a Unix socket fails silently Product: Base System Version: 12.0-RELEASE Hardware: Any OS: Any Status: New Severity: Affects Some People Priority: --- Component: kern Assignee: bugs@FreeBSD.org Reporter: bakaidl@gmail.com Created attachment 200893 --> https://bugs.freebsd.org/bugzilla/attachment.cgi?id=200893&action=edit Source for reproduction and patch When using the SO_PEERCRED getsockopt for a Unix socket from a Linux program with the Linux compatibility layer, it returns with no error, but the resulting struct ucred contains garbage. To reproduce, compile the attached linux_peercred_test.c for Linux, set up a listening Unix socket named test.sock on FreeBSD (nc -l -U test.sock or socat UNIX-LISTEN:test.sock -) and run linux_peercred_test. It will return something along the line of this: [bakaid@freebsd ~]$ ./linux_peercred_test uid: 4294965248, gid: 6, pid: 0 The cause seem to be the following: The Linux compat layer translates the Linux getsockopt for level SOL_SOCKET (1), optname SO_PEERCRED (17) to level SOL_SOCKET (0xffff), optname LOCAL_PEERCRED (1), and calls kern_getsockopt (sys/kern/uipc_syscalls.c) with these parameters (sys/compat/linux/linux_socket.c). However, LOCAL_PEERCRED should be called with level 0, not level SOL_SOCKET, as demonstrated (among others) by the getpeereid implementation (lib/libc/gen/getpeereid.c). Even worse, calling it with SOL_SOCKET will cause the getsockopt being served as a SOL_SOCKET request (kern_getsockopt -> sogetopt (sys/kern/uipc_socket.c)) and interpreted as SO_DEBUG (1), which will return successfully, causing the failure to be silent. I've only tried this on FreeBSD 12.0-RELEASE r341666 GENERIC amd64, but looking through the relevant git history I don't see positive evidence that this function ever worked properly. The attached patch (compat_linux_so_peercred_fix.patch) fixes the issue, which can be verified by running linux_peercred_test again: [bakaid@freebsd ~]$ ./linux_peercred_test uid: 1001, gid: 1001, pid: 0 -- You are receiving this mail because: You are the assignee for the bug.
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?bug-234722-227>
