From owner-freebsd-hackers@FreeBSD.ORG Thu Feb 21 14:08:12 2013 Return-Path: Delivered-To: freebsd-hackers@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by hub.freebsd.org (Postfix) with ESMTP id C0C3B199 for ; Thu, 21 Feb 2013 14:08:12 +0000 (UTC) (envelope-from nicholas@nickcwilson.co.uk) Received: from mail-vb0-f54.google.com (mail-vb0-f54.google.com [209.85.212.54]) by mx1.freebsd.org (Postfix) with ESMTP id 7BEF670C for ; Thu, 21 Feb 2013 14:08:11 +0000 (UTC) Received: by mail-vb0-f54.google.com with SMTP id l1so5772852vba.27 for ; Thu, 21 Feb 2013 06:08:10 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=x-received:mime-version:x-received:x-originating-ip:date:message-id :subject:from:to:content-type:x-gm-message-state; bh=bq1yLWBXe4Ofujga+BDXOQzn2c+N3h4F9qmAySGNJrg=; b=SrQdfotP0kef9cVa79XSxKtvvbARDTy/AfUpCEA0yLPPaO7Lc/4XfTqxaOnkS5Q5TX 46UdY11R3nXAWfxaBu3nSYV/IksV7T7WhsIeMs4eRyh3m5aZohxA5KJa/lXTP4sxfYp9 90RysAfQUmeEtUMcba1Nw9aZhIQIkXYE07+psCx0Jq0S3hj3YhDrOViAfgIDe07Moksh kXOpAWyiihseuAX6wQS22xhbZY6X2gkssBrdYaxUB1+08ZKyqNkkdrLqgLhv/CdoMPnX VfDB8ximuFyO+VA8M2/++HQp2LokO55yJvSrp4OcwbGRAYyFvQJU7mpjQ9JrK9mS6Nra F11Q== X-Received: by 10.58.40.9 with SMTP id t9mr32344100vek.10.1361455248481; Thu, 21 Feb 2013 06:00:48 -0800 (PST) Received: from mail-ve0-f178.google.com (mail-ve0-f178.google.com [209.85.128.178]) by mx.google.com with ESMTPS id q5sm84070234vdj.5.2013.02.21.06.00.48 (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Thu, 21 Feb 2013 06:00:48 -0800 (PST) Received: by mail-ve0-f178.google.com with SMTP id db10so7971076veb.9 for ; Thu, 21 Feb 2013 06:00:47 -0800 (PST) MIME-Version: 1.0 X-Received: by 10.52.24.98 with SMTP id t2mr27232876vdf.69.1361455247732; Thu, 21 Feb 2013 06:00:47 -0800 (PST) Received: by 10.58.200.226 with HTTP; Thu, 21 Feb 2013 06:00:47 -0800 (PST) X-Originating-IP: [2a02:390:a001:192:2010:aa2a:75ed:be50] Date: Thu, 21 Feb 2013 14:00:47 +0000 Message-ID: Subject: LOCAL_PEERCRED with socketpair From: Nicholas Wilson To: freebsd-hackers@freebsd.org X-Gm-Message-State: ALoCoQnA84aYQZ3rOgeJHKSWDL56R8fNXtSN3xkw3d6H0pBGZp2OPc7/VZa+VBJBoSC64k80gH5W Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable X-Content-Filtered-By: Mailman/MimeDel 2.1.14 X-BeenThere: freebsd-hackers@freebsd.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: Technical Discussions relating to FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 21 Feb 2013 14:08:12 -0000 Hello, I've noticed that getpeereid/LOCAL_PEERCRED doesn't work with sockets created through socketpair, but only through actual listen/connect calls. I notice that in unp_connect, we stash the peercred of the thread, then call on to unp_connect2. In kern_socketpair, we call straight through to unp_connect2 (through pr_usrreqs->pru_connect2), so this makes sense from the code. I'd like to suggest we support peercred for socketpair-created sockets. Motivation: 1. All unix-domain STREAM sockets should be created equal. We can support it, so why shouldn't we? 2. getpeerucred on Solaris, SO_PEERCRED on Linux, and of most relevance MacOS's implementation of LOCAL_PEERCRED all work fine on socketpair sockets. (A point against is that AIX's getpeereid follows the BSD behaviour of requiring a connect/listen call.) Programmers are therefore more likely to expect it to work than not. Apart from AIX, we're the only people not providing this capability. 3. Real-world uses. I was actually trying to sandbox a daemon with capsicum when I ran into this, which requires a certain amount of mucking around with file descriptor passing. Being able to establish a channel with a socketpair, hand it to a secure daemon, and be able to check the peer's credentials in the daemon, is a reasonable use-case. 4. Compatibility. It's not going to break old applications to make the change. Patch: --- sys/kern/uipc_syscalls.c.RELEASE-9.1-243808 2013-02-21 13:37:31.778270145 +0000 +++ sys/kern/uipc_syscalls.c 2013-02-21 13:45:58.747896673 +0000 @@ -642,6 +642,19 @@ error =3D soconnect2(so2, so1); if (error) goto free4; + } else if (type =3D=3D SOCK_STREAM) { + struct unpcb *unp, *unp2; + unp =3D sotounpcb(so1); + unp2 =3D sotounpcb(so2); + UNP_PCB_LOCK(unp); + UNP_PCB_LOCK(unp2); + cru2x(td->td_ucred, &unp->unp_peercred); + memcpy(&unp2->unp_peercred, &unp->unp_peercred, + sizeof(unp2->unp_peercred)); + unp->unp_flags |=3D UNP_HAVEPC; + unp2->unp_flags |=3D UNP_HAVEPC; + UNP_PCB_UNLOCK(unp); + UNP_PCB_UNLOCK(unp2); } finit(fp1, FREAD | FWRITE, DTYPE_SOCKET, fp1->f_data, &socketops); finit(fp2, FREAD | FWRITE, DTYPE_SOCKET, fp2->f_data, &socketops); I've not looked into the FreeBSD kernel before, so the patch may be useless! I think conceptually it's the right place to put it though. unix.4.man and getpeereid.3.man would have to be updated also. Best wishes, Nicholas ----- Nicholas Wilson: nicholas@nicholaswilson.me.uk Site and blog: www.nicholaswilson.me.uk 6 Tribune Court, CB4 2TU 07845=E2=80=AF182898