Summary: | [linux] [patch] Add partial support for SO_PEERCRED in Linux emulation | ||||||
---|---|---|---|---|---|---|---|
Product: | Base System | Reporter: | Marcin Cieslak <saper> | ||||
Component: | kern | Assignee: | Dmitry Chagin <dchagin> | ||||
Status: | Closed FIXED | ||||||
Severity: | Affects Only Me | ||||||
Priority: | Normal | ||||||
Version: | Unspecified | ||||||
Hardware: | Any | ||||||
OS: | Any | ||||||
Attachments: |
|
Description
Marcin Cieslak
2006-09-07 00:50:19 UTC
Responsible Changed From-To: freebsd-bugs->freebsd-emulation Over to maintainer(s). Responsible Changed From-To: freebsd-emulation->rink I will deal with this - this PR has been gone unnoticed for far too long and we use the patch at work for a long time with no ill effects. On Thu, 7 Sep 2006, Mark Linimon wrote: > Synopsis: [linux] [patch] Add partial support for SO_PEERCRED in Linux emulation > > Responsible-Changed-From-To: freebsd-bugs->freebsd-emulation > Responsible-Changed-By: linimon > Responsible-Changed-When: Thu Sep 7 01:58:41 UTC 2006 > Responsible-Changed-Why: > Over to maintainer(s). FYI, I have three concerns about this patch: (1) The value of LINUX_SO_PEERCRED is incorrect for Alpha, it should be 18 on that platform. (2) I'm a bit worried about pid not being set, but this may (may) be OK. On Linux, generally speaking you are guaranteed that either you get (0, -1, -1) or (pid, uid, gid), but not a blend of both. As we support the pid for SCM_CREDS, we might also consider adding a LOCAL_PEERPID for use by the linux emulator to query the remote pid (we'd need to add that where the peercred is currently cached though). (3) LOG_WARNING should perhaps be LOG_DEBUG or something more consistent with the res of the linuxulator. FYI, I'm not sure I like that we just pass all other socket options through to getsockopt() without transformation or an error, it seems failure-prone. We may end up returning invalid data, etc, but that's not caused by this patch, but a generally poor failure mode in the linuxulator. Robert N M Watson Computer Laboratory University of Cambridge Hello, > (1) The value of LINUX_SO_PEERCRED is incorrect for Alpha, it should be 18 on > that platform. Well, in the meantime Alpha support is gone... > (2) I'm a bit worried about pid not being set, but this may (may) be OK. On > Linux, generally speaking you are guaranteed that either you get (0, -1, > -1) or (pid, uid, gid), but not a blend of both. As we support the pid > for SCM_CREDS, we might also consider adding a LOCAL_PEERPID for use by > the linux emulator to query the remote pid (we'd need to add that where > the peercred is currently cached though). Will remote PID always be available? > > (3) LOG_WARNING should perhaps be LOG_DEBUG or something more consistent with > the res of the linuxulator. I agree. This should be LOG_DEBUG. > FYI, I'm not sure I like that we just pass all other socket options through to > getsockopt() without transformation or an error, it seems failure-prone. We > may end up returning invalid data, etc, but that's not caused by this patch, > but a generally poor failure mode in the linuxulator. I agree. Probably we should explicitly list all supported socket option. I think most of the translation layer is coded for "fixing known differences" vs. "explicit support for X, Y, Z returning EA, EB or EC". --Marcin Responsible Changed From-To: rink->dchagin grab PR, discussed with rink. Author: dchagin Date: Sat May 16 18:42:18 2009 New Revision: 192203 URL: http://svn.freebsd.org/changeset/base/192203 Log: Emulate SO_PEERCRED socket option. Temporarily use 0 for pid member as the FreeBSD does not cache remote UNIX domain socket peer pid. PR: kern/102956 Reviewed by: rwatson Approved by: kib (mentor) MFC after: 1 month Modified: head/sys/compat/linux/linux_socket.c head/sys/compat/linux/linux_socket.h Modified: head/sys/compat/linux/linux_socket.c ============================================================================== --- head/sys/compat/linux/linux_socket.c Sat May 16 18:08:28 2009 (r192202) +++ head/sys/compat/linux/linux_socket.c Sat May 16 18:42:18 2009 (r192203) @@ -1354,7 +1354,9 @@ linux_getsockopt(struct thread *td, stru } */ bsd_args; l_timeval linux_tv; struct timeval tv; - socklen_t tv_len; + socklen_t tv_len, xulen; + struct xucred xu; + struct l_ucred lxu; int error, name; bsd_args.s = args->s; @@ -1377,6 +1379,23 @@ linux_getsockopt(struct thread *td, stru sizeof(linux_tv))); /* NOTREACHED */ break; + case LOCAL_PEERCRED: + if (args->optlen != sizeof(lxu)) + return (EINVAL); + xulen = sizeof(xu); + error = kern_getsockopt(td, args->s, bsd_args.level, + name, &xu, UIO_SYSSPACE, &xulen); + if (error) + return (error); + /* + * XXX Use 0 for pid as the FreeBSD does not cache peer pid. + */ + lxu.pid = 0; + lxu.uid = xu.cr_uid; + lxu.gid = xu.cr_gid; + return (copyout(&lxu, PTRIN(args->optval), sizeof(lxu))); + /* NOTREACHED */ + break; default: break; } Modified: head/sys/compat/linux/linux_socket.h ============================================================================== --- head/sys/compat/linux/linux_socket.h Sat May 16 18:08:28 2009 (r192202) +++ head/sys/compat/linux/linux_socket.h Sat May 16 18:42:18 2009 (r192203) @@ -90,4 +90,10 @@ #define LINUX_AF_APPLETALK 5 #define LINUX_AF_INET6 10 +struct l_ucred { + uint32_t pid; + uint32_t uid; + uint32_t gid; +}; + #endif /* _LINUX_SOCKET_H_ */ _______________________________________________ svn-src-all@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/svn-src-all To unsubscribe, send any mail to "svn-src-all-unsubscribe@freebsd.org" State Changed From-To: open->patched commited to current. Author: dchagin Date: Tue Jun 16 05:05:46 2009 New Revision: 194281 URL: http://svn.freebsd.org/changeset/base/194281 Log: MFC r192203: Emulate SO_PEERCRED socket option. Temporarily use 0 for pid member as the FreeBSD does not cache remote UNIX domain socket peer pid. PR: kern/102956 Approved by: kib (mentor) Modified: stable/7/sys/ (props changed) stable/7/sys/compat/linux/linux_socket.c stable/7/sys/compat/linux/linux_socket.h stable/7/sys/contrib/pf/ (props changed) stable/7/sys/dev/ath/ath_hal/ (props changed) Modified: stable/7/sys/compat/linux/linux_socket.c ============================================================================== --- stable/7/sys/compat/linux/linux_socket.c Tue Jun 16 03:51:38 2009 (r194280) +++ stable/7/sys/compat/linux/linux_socket.c Tue Jun 16 05:05:46 2009 (r194281) @@ -1159,7 +1159,9 @@ linux_getsockopt(struct thread *td, stru } */ bsd_args; l_timeval linux_tv; struct timeval tv; - socklen_t tv_len; + socklen_t tv_len, xulen; + struct xucred xu; + struct l_ucred lxu; int error, name; bsd_args.s = args->s; @@ -1182,6 +1184,23 @@ linux_getsockopt(struct thread *td, stru sizeof(linux_tv))); /* NOTREACHED */ break; + case LOCAL_PEERCRED: + if (args->optlen != sizeof(lxu)) + return (EINVAL); + xulen = sizeof(xu); + error = kern_getsockopt(td, args->s, bsd_args.level, + name, &xu, UIO_SYSSPACE, &xulen); + if (error) + return (error); + /* + * XXX Use 0 for pid as the FreeBSD does not cache peer pid. + */ + lxu.pid = 0; + lxu.uid = xu.cr_uid; + lxu.gid = xu.cr_gid; + return (copyout(&lxu, PTRIN(args->optval), sizeof(lxu))); + /* NOTREACHED */ + break; default: break; } Modified: stable/7/sys/compat/linux/linux_socket.h ============================================================================== --- stable/7/sys/compat/linux/linux_socket.h Tue Jun 16 03:51:38 2009 (r194280) +++ stable/7/sys/compat/linux/linux_socket.h Tue Jun 16 05:05:46 2009 (r194281) @@ -59,4 +59,10 @@ #define LINUX_AF_APPLETALK 5 #define LINUX_AF_INET6 10 +struct l_ucred { + uint32_t pid; + uint32_t uid; + uint32_t gid; +}; + #endif /* _LINUX_SOCKET_H_ */ _______________________________________________ svn-src-all@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/svn-src-all To unsubscribe, send any mail to "svn-src-all-unsubscribe@freebsd.org" State Changed From-To: patched->closed Feedback timeout. 6.1 still don't have SO_PEERCRED support. This PR was opened in 2006 by Marcin Cieslak. His reason was Oracle XE not running correctly due to the usage of the linux SO_PEERCRED option. He wrote a patch for this that worked without any known problems. This patch was rewritten by dchagin in May and June 2009. He changed one significant detail. While in the original patch the following comparison was made: + if (optlen < sizeof(linux_ucred)) + return (EFAULT); dchagin rewrote this to: + if (args->optlen != sizeof(lxu)) + return (EINVAL); However, due to this change, Oracle XE's setsockopt call for SO_PEERCRED will fail with EINVAL. For Oracle to work successfully, the patch should contain: + if (args->optlen < sizeof(lxu)) + return (EINVAL); It seems that Oracle passes in a structure that is larger than the struct linux_ucred defined in this patch. Why? Don't know, haven't had time to debug this in detail. As Oracle XE would not run on a new system with 8-STABLE I investigated and by comparing both the old patch and current code I quickly came to the conclusion above. Changing the comparison in linux_socket back to a smaller-than comparison solved the problem. The original patch has been running in a production situation for a couple of years now and no problems have surfaced. Checking that the structure is sufficiently large should guarantee stability. There is no need for the kernel to return EINVAL if a larger structure was passed in. If requested, I am willing to investigate further. Kind regards, Roel Bouwman. -- QSP Internet Services / Quality Service Provider BV Postbus 9340 5000 HH Tilburg The Netherlands Tel. +31 135810451 Fax. +31 135810454 Mob. +31 618782702 E-mail: roel@qsp.nl A commit references this bug: Author: dchagin Date: Sat Mar 18 18:31:04 UTC 2017 New revision: 315503 URL: https://svnweb.freebsd.org/changeset/base/315503 Log: As noted by Roel Bouwman Linux allows a large buffer size than the struct ucred size. Fix this. PR: 102956 Reported by: Roel Bouwman <roel at qsp nl> MFC after: 1 week Changes: head/sys/compat/linux/linux_socket.c A commit references this bug: Author: dchagin Date: Sat Mar 25 14:26:46 UTC 2017 New revision: 315954 URL: https://svnweb.freebsd.org/changeset/base/315954 Log: MFC r315503: As noted by Roel Bouwman Linux allows a large buffer size than the struct ucred size. Fix this. PR: 102956 Changes: _U stable/11/ stable/11/sys/compat/linux/linux_socket.c |