From saper@saper.info  Wed Sep  6 23:43:52 2006
Return-Path: <saper@saper.info>
Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125])
	by hub.freebsd.org (Postfix) with ESMTP id 1ED4216A4E1
	for <FreeBSD-gnats-submit@freebsd.org>; Wed,  6 Sep 2006 23:43:52 +0000 (UTC)
	(envelope-from saper@saper.info)
Received: from cable-201-87.iesy.tv (cable-201-87.iesy.net [81.210.201.87])
	by mx1.FreeBSD.org (Postfix) with ESMTP id E562C43D7D
	for <FreeBSD-gnats-submit@freebsd.org>; Wed,  6 Sep 2006 23:43:39 +0000 (GMT)
	(envelope-from saper@saper.info)
Received: from saperski.saper.info (saperski.saper.info [127.0.0.1])
	by cable-201-87.iesy.tv (8.13.6/8.13.6) with ESMTP id k86NhLmo004350
	for <FreeBSD-gnats-submit@freebsd.org>; Thu, 7 Sep 2006 01:43:21 +0200 (CEST)
	(envelope-from saper@saperski.saper.info)
Received: (from saper@localhost)
	by saperski.saper.info (8.13.6/8.13.6/Submit) id k86NhLhT004349;
	Thu, 7 Sep 2006 01:43:21 +0200 (CEST)
	(envelope-from saper)
Message-Id: <200609062343.k86NhLhT004349@saperski.saper.info>
Date: Thu, 7 Sep 2006 01:43:21 +0200 (CEST)
From: Marcin Cieslak <saper@SYSTEM.PL>
Reply-To: Marcin Cieslak <saper@SYSTEM.PL>
To: FreeBSD-gnats-submit@freebsd.org
Cc:
Subject: Add partial support for SO_PEERCRED in Linux emulation
X-Send-Pr-Version: 3.113
X-GNATS-Notify:

>Number:         102956
>Category:       kern
>Synopsis:       [linux] [patch] Add partial support for SO_PEERCRED in Linux emulation
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    dchagin
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          change-request
>Submitter-Id:   current-users
>Arrival-Date:   Wed Sep 06 23:50:19 GMT 2006
>Closed-Date:    Mon Jul 05 20:28:57 UTC 2010
>Last-Modified:  Fri Sep 24 13:40:01 UTC 2010
>Originator:     Marcin Cieslak
>Release:        FreeBSD 6.1-RC i386
>Organization:
System Business Consulting
>Environment:
System: FreeBSD saperski.saper.info 6.1-RC FreeBSD 6.1-RC #10: Fri Sep 1 02:20:15 CEST 2006 saper@saperski.saper.info:/usr/obj/usr/src/sys/VAIO i386


>Description:

Current Linux getsockopt() does not support SO_PEERCRED option used to fetch UNIX domain
socket peer PID, UID and GID. 

Without this option ORACLE 10i Express Edition lsnrctl is unable to issue commands
to a running listener (including "status" and "stop").
All invocations result in the message:

TNS-01189: The listener could not authenticate the user

Linux lsnrctl using so called "OS Authentication" mode probes if UNIX socket
connection peer is the process run under to privileged "dba" group (or another group
listed in the DBA_GROUP parameter of the $ORACLE_HOME/network/admin/listener.ora file).

Security of this patch is not tested.

Known problem: Peer PID recognition is not done, we always return zero.

>How-To-Repeat:

Perform "${ORACLE_HOME}/bin/lsnrctl status" as the Oracle user.

>Fix:

Modified files:
     $FreeBSD: src/sys/compat/linux/linux_socket.c,v 1.59.2.1 2006/01/10 10:12:55 glebius Exp $
     $FreeBSD: src/sys/i386/linux/linux.h,v 1.64 2005/04/13 04:31:43 mdodd Exp $
     $FreeBSD: src/sys/amd64/linux32/linux.h,v 1.1 2004/08/16 07:55:06 tjr Exp $
     $FreeBSD: src/sys/alpha/linux/linux.h,v 1.59 2004/08/16 07:05:44 tjr Exp $


--- /sys/i386/linux/linux.h.orig	Wed Sep  6 20:36:43 2006
+++ /sys/i386/linux/linux.h	Wed Sep  6 20:37:15 2006
@@ -615,6 +615,7 @@
 #define	LINUX_SO_NO_CHECK	11
 #define	LINUX_SO_PRIORITY	12
 #define	LINUX_SO_LINGER		13
+#define	LINUX_SO_PEERCRED	17
 
 #define	LINUX_IP_TOS		1
 #define	LINUX_IP_TTL		2
--- /sys/alpha/linux/linux.h.orig	Sun Oct  3 12:52:08 2004
+++ /sys/alpha/linux/linux.h	Thu Sep  7 00:58:26 2006
@@ -447,6 +447,7 @@
 #define	LINUX_SO_NO_CHECK	11
 #define	LINUX_SO_PRIORITY	12
 #define	LINUX_SO_LINGER		13
+#define	LINUX_SO_PEERCRED	17
 
 #define	LINUX_IP_TOS		1
 #define	LINUX_IP_TTL		2
--- /sys/amd64/linux32/linux.h.orig	Mon Aug 16 09:55:06 2004
+++ /sys/amd64/linux32/linux.h	Thu Sep  7 00:58:01 2006
@@ -635,6 +635,7 @@
 #define	LINUX_SO_NO_CHECK	11
 #define	LINUX_SO_PRIORITY	12
 #define	LINUX_SO_LINGER		13
+#define	LINUX_SO_PEERCRED	17
 
 #define	LINUX_IP_TOS		1
 #define	LINUX_IP_TTL		2
--- /sys/compat/linux/linux_socket.c.orig	Thu Sep  7 01:04:09 2006
+++ /sys/compat/linux/linux_socket.c	Thu Sep  7 01:06:29 2006
@@ -27,7 +27,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: /repoman/r/ncvs/src/sys/compat/linux/linux_socket.c,v 1.59.2.1 2006/01/10 10:12:55 glebius Exp $");
+__FBSDID("$FreeBSD: src/sys/compat/linux/linux_socket.c,v 1.59.2.1 2006/01/10 10:12:55 glebius Exp $");
 
 /* XXX we use functions that might not exist. */
 #include "opt_compat.h"
@@ -39,6 +39,7 @@
 
 #include <sys/param.h>
 #include <sys/proc.h>
+#include <sys/syslog.h>
 #include <sys/systm.h>
 #include <sys/sysproto.h>
 #include <sys/fcntl.h>
@@ -53,6 +54,7 @@
 #include <sys/syscallsubr.h>
 #include <sys/uio.h>
 #include <sys/syslog.h>
+#include <sys/un.h>
 
 #include <netinet/in.h>
 #include <netinet/in_systm.h>
@@ -299,6 +301,8 @@
 		return (SO_OOBINLINE);
 	case LINUX_SO_LINGER:
 		return (SO_LINGER);
+	case LINUX_SO_PEERCRED:
+		return (LOCAL_PEERCRED);
 	}
 	return (-1);
 }
@@ -1114,7 +1118,13 @@
 		caddr_t val;
 		int *avalsize;
 	} */ bsd_args;
-	int error, name;
+	struct linux_ucred {
+		uint32_t pid;
+		uint32_t uid;
+		uint32_t gid;
+	} linux_ucred;
+	struct xucred xuc;
+	int error, name, optlen, rc, xuclen;
 
 	if ((error = copyin(args, &linux_args, sizeof(linux_args))))
 		return (error);
@@ -1136,13 +1146,43 @@
 		name = -1;
 		break;
 	}
-	if (name == -1)
+	if (name == -1) {
+		log(LOG_WARNING, "LINUX: 'getsockopt' level=0x%04x"
+			"optname=0x%04x not implemented\n", 
+			linux_args.level, linux_args.optname);
 		return (EINVAL);
+	};
 
 	bsd_args.name = name;
-	bsd_args.val = PTRIN(linux_args.optval);
-	bsd_args.avalsize = PTRIN(linux_args.optlen);
-	return (getsockopt(td, &bsd_args));
+	if (bsd_args.level == SOL_SOCKET && name == LOCAL_PEERCRED) {
+		if ((error = copyin(PTRIN(linux_args.optval), 
+			&linux_ucred, sizeof(linux_ucred))))
+			return (error);
+		if ((error = copyin(PTRIN(linux_args.optlen), 
+			&optlen, sizeof(optlen))))
+			return (error);
+		if (optlen < sizeof(linux_ucred)) 
+			return (EFAULT);
+		xuclen = sizeof(xuc);
+		if ((rc = error = kern_getsockopt(td, bsd_args.s,
+			0, bsd_args.name, 
+			(caddr_t) &xuc, UIO_SYSSPACE, &xuclen))) 
+			return (error);
+		if (xuc.cr_version != XUCRED_VERSION) 
+			return (EINVAL);
+		/* XXX get PID */
+		linux_ucred.pid = 0;
+		linux_ucred.uid = xuc.cr_uid;
+		linux_ucred.gid = xuc.cr_gid;
+		if ((error = copyout(&linux_ucred,
+			PTRIN(linux_args.optval), sizeof(linux_ucred))))
+			return (error);
+		return (rc);
+	} else {
+		bsd_args.val = PTRIN(linux_args.optval);
+		bsd_args.avalsize = PTRIN(linux_args.optlen);
+		return (getsockopt(td, &bsd_args));
+	};
 }
 
 int
>Release-Note:
>Audit-Trail:
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). 

http://www.freebsd.org/cgi/query-pr.cgi?pr=102956 
Responsible-Changed-From-To: freebsd-emulation->rink 
Responsible-Changed-By: rink 
Responsible-Changed-When: Fri Mar 14 08:42:14 UTC 2008 
Responsible-Changed-Why:  
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. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=102956 

From: Robert Watson <rwatson@FreeBSD.org>
To: bug-followup@FreeBSD.org
Cc:  
Subject: Re: kern/102956: [linux] [patch] Add partial support for	SO_PEERCRED
 in Linux emulation
Date: Fri, 14 Mar 2008 12:20:40 +0000 (GMT)

 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

From: Marcin Cieslak <saper@system.pl>
To: bug-followup@FreeBSD.org
Cc: Robert Watson <rwatson@FreeBSD.org>, rdivacky@FreeBSD.org,
  rink@FreeBSD.org
Subject: Re: kern/102956: [linux] [patch] Add partial support for SO_PEERCRED
 in Linux emulation
Date: Tue, 09 Sep 2008 17:09:27 +0200

 This is an OpenPGP/MIME signed message (RFC 2440 and 3156)
 --------------enig4C256BDCE0C1E5115289672A
 Content-Type: text/plain; charset=ISO-8859-2; format=flowed
 Content-Transfer-Encoding: quoted-printable
 
 
 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=
 =2E 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?
 >=20
 > (3) LOG_WARNING should perhaps be LOG_DEBUG or something more consisten=
 t 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=20
 through to
 > getsockopt() without transformation or an error, it seems failure-prone=
 =2E We
 > may end up returning invalid data, etc, but that's not caused by this p=
 atch,
 > 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=20
 differences" vs. "explicit support for X, Y, Z returning EA, EB or EC".
 
 --Marcin
 
 
 --------------enig4C256BDCE0C1E5115289672A
 Content-Type: application/pgp-signature; name="signature.asc"
 Content-Description: OpenPGP digital signature
 Content-Disposition: attachment; filename="signature.asc"
 
 -----BEGIN PGP SIGNATURE-----
 
 iQCVAwUBSMaRqz2W2v2wY27ZAQMSjQQAk1cWPPpb+a/lzUqVTDK5UPF62rjUVABD
 5najGil8hJTcwvErzY12FLISIE+pql6rGcKKfVuP3RKR19fBmGMxeRviu8pWdF+2
 wrBvcOelWavZH2qEgqd8F25F+3x2SK+QnB4SHme+OYdlOUZyGUtIZaUUWH0sbhki
 7UvSZLisI+8=
 =9JK1
 -----END PGP SIGNATURE-----
 
 --------------enig4C256BDCE0C1E5115289672A--
Responsible-Changed-From-To: rink->dchagin 
Responsible-Changed-By: dchagin 
Responsible-Changed-When: Mon Mar 16 18:27:06 UTC 2009 
Responsible-Changed-Why:  
grab PR, discussed with rink. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=102956 

From: dfilter@FreeBSD.ORG (dfilter service)
To: bug-followup@FreeBSD.org
Cc:  
Subject: Re: kern/102956: commit references a PR
Date: Sat, 16 May 2009 18:42:30 +0000 (UTC)

 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 
State-Changed-By: dchagin 
State-Changed-When: Sat May 16 21:50:27 UTC 2009 
State-Changed-Why:  
commited to current. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=102956 

From: dfilter@FreeBSD.ORG (dfilter service)
To: bug-followup@FreeBSD.org
Cc:  
Subject: Re: kern/102956: commit references a PR
Date: Tue, 16 Jun 2009 05:06:00 +0000 (UTC)

 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 
State-Changed-By: dchagin 
State-Changed-When: Mon Jul 5 20:27:24 UTC 2010 
State-Changed-Why:  

Feedback timeout. 6.1 still don't have SO_PEERCRED support. 


http://www.freebsd.org/cgi/query-pr.cgi?pr=102956 

From: Roel Bouwman <roel@qsp.nl>
To: bug-followup@freebsd.org
Cc: saper@SYSTEM.PL
Subject: Re: kern/102956: [linux] [patch] Add partial support for SO_PEERCRED in Linux emulation
Date: Fri, 24 Sep 2010 15:16:19 +0200

 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
>Unformatted:
