PERFORCE change 164408 for review

Robert Watson rwatson at FreeBSD.org
Mon Jun 15 09:12:21 UTC 2009


http://perforce.freebsd.org/chv.cgi?CH=164408

Change 164408 by rwatson at rwatson_freebsd_capabilities on 2009/06/15 09:11:55

	Implement _rights() variants of libcapability RPC calls, which
	should (in principle) allow sets of file descriptors/capabilities
	to be attached to remote procedure calls in either direction.

Affected files ...

.. //depot/projects/trustedbsd/capabilities/src/lib/libcapability/libcapability.c#9 edit
.. //depot/projects/trustedbsd/capabilities/src/lib/libcapability/libcapability.h#16 edit
.. //depot/projects/trustedbsd/capabilities/src/lib/libcapability/libcapability_host_io.c#3 edit
.. //depot/projects/trustedbsd/capabilities/src/lib/libcapability/libcapability_internal.h#3 edit
.. //depot/projects/trustedbsd/capabilities/src/lib/libcapability/libcapability_sandbox_io.c#3 edit

Differences ...

==== //depot/projects/trustedbsd/capabilities/src/lib/libcapability/libcapability.c#9 (text+ko) ====

@@ -30,7 +30,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $P4: //depot/projects/trustedbsd/capabilities/src/lib/libcapability/libcapability.c#8 $
+ * $P4: //depot/projects/trustedbsd/capabilities/src/lib/libcapability/libcapability.c#9 $
  */
 
 #include <sys/types.h>
@@ -64,6 +64,15 @@
 	return (0);
 }
 
+void
+_lc_dispose_rights(int *fdp, int fdcount)
+{
+	int i;
+
+	for (i = 0; i < fdcount; i++)
+		close(fdp[i]);
+}
+
 /*
  * Given a 'struct msghdr' returned by a successful call to recvmsg(),
  * extract up to the desired number of file descriptors (or clean up the
@@ -100,8 +109,7 @@
 			cmsg_fdp = (int *)CMSG_DATA(cmsg);
 			fdcount = (cmsg->cmsg_len - CMSG_LEN(0)) /
 			    sizeof(int);
-			for (i = 0; i < fdcount; i++)
-				close(cmsg_fdp[i]);
+			_lc_dispose_rights(cmsg_fdp, fdcount);
 		}
 		errno = EBADMSG;
 		return (-1);

==== //depot/projects/trustedbsd/capabilities/src/lib/libcapability/libcapability.h#16 (text+ko) ====

@@ -30,7 +30,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $P4: //depot/projects/trustedbsd/capabilities/src/lib/libcapability/libcapability.h#15 $
+ * $P4: //depot/projects/trustedbsd/capabilities/src/lib/libcapability/libcapability.h#16 $
  */
 
 #ifndef _LIBCAPABILITY_H_
@@ -87,8 +87,9 @@
 int	lch_rpc(struct lc_sandbox *lcsp, u_int32_t opno, struct iovec *req,
 	    int reqcount, struct iovec *rep, int repcount, size_t *replenp);
 int	lch_rpc_rights(struct lc_sandbox *lcsp, u_int32_t opno,
-	    struct iovec *req, int reqcount, int *req_fdp, int *req_fdcount,
-	    struct iovec *rep, int repcount, int *rep_fdp, int *rep_fdcount);
+	    struct iovec *req, int reqcount, int *req_fdp, int req_fdcount,
+	    struct iovec *rep, int repcount, size_t *replenp, int *rep_fdp,
+	    int *rep_fdcount);
 
 /*
  * Interfaces to query state from within capability mode sandboxes.
@@ -119,7 +120,7 @@
 	    struct iovec *rep, int repcount);
 int	lcs_sendrpc_rights(struct lc_host *lchp, u_int32_t opno,
 	    u_int32_t seqno, struct iovec *rep, int repcount, int *fdp,
-	    int *fdcountp);
+	    int fdcount);
 
 /*
  * Actually an rtld-elf-cap symbol, but declared here so it is available to

==== //depot/projects/trustedbsd/capabilities/src/lib/libcapability/libcapability_host_io.c#3 (text+ko) ====

@@ -30,7 +30,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $P4: //depot/projects/trustedbsd/capabilities/src/lib/libcapability/libcapability_host_io.c#2 $
+ * $P4: //depot/projects/trustedbsd/capabilities/src/lib/libcapability/libcapability_host_io.c#3 $
  */
 
 #include <sys/param.h>
@@ -97,9 +97,10 @@
  * don't need retransmission, and are synchronous.  However, it might not be
  * a bad idea to use them anyway.
  */
-int
-lch_rpc(struct lc_sandbox *lcsp, u_int32_t opno, struct iovec *req,
-    int reqcount, struct iovec *rep, int repcount, size_t *replenp)
+static int
+lch_rpc_internal(struct lc_sandbox *lcsp, u_int32_t opno, struct iovec *req,
+    int reqcount, int *req_fdp, int req_fdcount, struct iovec *rep,
+    int repcount, size_t *replenp, int *rep_fdp, int *rep_fdcountp)
 {
 	struct lcrpc_request_hdr req_hdr;
 	struct lcrpc_reply_hdr rep_hdr;
@@ -119,7 +120,11 @@
 	/*
 	 * Send our header.
 	 */
-	len = lch_send(lcsp, &req_hdr, sizeof(req_hdr), 0);
+	if (req_fdp != NULL)
+		len = lch_send_rights(lcsp, &req_hdr, sizeof(req_hdr), 0,
+		    req_fdp, req_fdcount);
+	else
+		len = lch_send(lcsp, &req_hdr, sizeof(req_hdr), 0);
 	if (len < 0)
 		return (-1);
 	if (len != sizeof(req_hdr)) {
@@ -143,10 +148,16 @@
 	/*
 	 * Receive our header and validate.
 	 */
-	len = lch_recv(lcsp, &rep_hdr, sizeof(rep_hdr), MSG_WAITALL);
+	if (rep_fdp != NULL)
+		len = lch_recv_rights(lcsp, &rep_hdr, sizeof(rep_hdr),
+		    MSG_WAITALL, rep_fdp, rep_fdcountp);
+	else
+		len = lch_recv(lcsp, &rep_hdr, sizeof(rep_hdr), MSG_WAITALL);
 	if (len < 0)
 		return (-1);
 	if (len != sizeof(rep_hdr)) {
+		if (rep_fdp != NULL)
+			_lc_dispose_rights(rep_fdp, *rep_fdcountp);
 		errno = ECHILD;
 		return (-1);
 	}
@@ -155,6 +166,8 @@
 	    rep_hdr.lcrpc_rephdr_seqno != 0 ||
 	    rep_hdr.lcrpc_rephdr_opno != opno ||
 	    rep_hdr.lcrpc_rephdr_datalen > req_hdr.lcrpc_reqhdr_maxrepdatalen) {
+		if (rep_fdp != NULL)
+			_lc_dispose_rights(rep_fdp, *rep_fdcountp);
 		errno = EBADRPC;
 		return (-1);
 	}
@@ -176,6 +189,9 @@
 			if (len < 0)
 				return (-1);
 			if ((size_t)len != want) {
+				if (rep_fdp != NULL)
+					_lc_dispose_rights(rep_fdp,
+					    *rep_fdcountp);
 				errno = ECHILD;
 				return (-1);
 			}
@@ -190,3 +206,22 @@
 	*replenp = totlen;
 	return (0);
 }
+
+int
+lch_rpc(struct lc_sandbox *lcsp, u_int32_t opno, struct iovec *req,
+    int reqcount, struct iovec *rep, int repcount, size_t *replenp)
+{
+
+	return (lch_rpc_internal(lcsp, opno, req, reqcount, NULL, 0,
+	    rep, repcount, replenp, NULL, NULL));
+}
+
+int
+lch_rpc_rights(struct lc_sandbox *lcsp, u_int32_t opno, struct iovec *req,
+    int reqcount, int *req_fdp, int req_fdcount, struct iovec *rep,
+    int repcount, size_t *replenp, int *rep_fdp, int *rep_fdcountp)
+{
+
+	return (lch_rpc_internal(lcsp, opno, req, reqcount, req_fdp,
+	    req_fdcount, rep, repcount, replenp, rep_fdp, rep_fdcountp));
+}

==== //depot/projects/trustedbsd/capabilities/src/lib/libcapability/libcapability_internal.h#3 (text+ko) ====

@@ -30,7 +30,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $P4: //depot/projects/trustedbsd/capabilities/src/lib/libcapability/libcapability_internal.h#2 $
+ * $P4: //depot/projects/trustedbsd/capabilities/src/lib/libcapability/libcapability_internal.h#3 $
  */
 
 #ifndef _LIBCAPABILITY_INTERNAL_H_
@@ -47,6 +47,7 @@
 };
 
 struct msghdr;
+void	_lc_dispose_rights(int *fdp, int fdcount);
 int	_lc_receive_rights(struct msghdr *msg, int *fdp, int *fdcountp);
 
 ssize_t	_lc_recv(int fd, void *buf, size_t len, int flags);

==== //depot/projects/trustedbsd/capabilities/src/lib/libcapability/libcapability_sandbox_io.c#3 (text+ko) ====

@@ -85,9 +85,10 @@
  * variable size, space is allocated by the RPC code rather than the caller,
  * who is expected to free it with free(3) if desired.
  */
-int
-lcs_recvrpc(struct lc_host *lchp, u_int32_t *opnop, u_int32_t *seqnop,
-    u_char **bufferp, size_t *lenp)
+static int
+lcs_recvrpc_internal(struct lc_host *lchp, u_int32_t *opnop,
+    u_int32_t *seqnop, u_char **bufferp, size_t *lenp, int *fdp,
+    int *fdcountp)
 {
 	struct lcrpc_request_hdr req_hdr;
 	size_t totlen;
@@ -95,19 +96,29 @@
 	u_char *buffer;
 	int error;
 
-	len = lcs_recv(lchp, &req_hdr, sizeof(req_hdr), MSG_WAITALL);
+	if (fdp != NULL)
+		len = lcs_recv_rights(lchp, &req_hdr, sizeof(req_hdr),
+		    MSG_WAITALL, fdp, fdcountp);
+	else
+		len = lcs_recv(lchp, &req_hdr, sizeof(req_hdr), MSG_WAITALL);
 	if (len < 0)
 		return (-1);
 	if (len == 0) {
+		if (fdp != NULL)
+			_lc_dispose_rights(fdp, *fdcountp);
 		errno = EPIPE;
 		return (-1);
 	}
 	if (len != sizeof(req_hdr)) {
+		if (fdp != NULL)
+			_lc_dispose_rights(fdp, *fdcountp);
 		errno = EBADMSG;
 		return (-1);
 	}
 
 	if (req_hdr.lcrpc_reqhdr_magic != LCRPC_REQUEST_HDR_MAGIC) {
+		if (fdp != NULL)
+			_lc_dispose_rights(fdp, *fdcountp);
 		errno = EBADMSG;
 		return (-1);
 	}
@@ -122,8 +133,13 @@
 	 * What about if there are other socket errors, such as EINTR?
 	 */
 	buffer = malloc(req_hdr.lcrpc_reqhdr_datalen);
-	if (buffer == NULL)
+	if (buffer == NULL) {
+		error = errno;
+		if (fdp != NULL)
+			_lc_dispose_rights(fdp, *fdcountp);
+		errno = error;
 		return (-1);
+	}
 
 	/*
 	 * XXXRW: Likewise, how to handle failure at this stage?
@@ -134,11 +150,15 @@
 		    req_hdr.lcrpc_reqhdr_datalen - totlen, MSG_WAITALL);
 		if (len < 0) {
 			error = errno;
+			if (fdp != NULL)
+				_lc_dispose_rights(fdp, *fdcountp);
 			free(buffer);
 			return (-1);
 		}
 		if (len == 0) {
 			errno = EPIPE;
+			if (fdp != NULL)
+				_lc_dispose_rights(fdp, *fdcountp);
 			free(buffer);
 			return (-1);
 		}
@@ -152,8 +172,26 @@
 }
 
 int
-lcs_sendrpc(struct lc_host *lchp, u_int32_t opno, u_int32_t seqno,
-    struct iovec *rep, int repcount)
+lcs_recvrpc(struct lc_host *lchp, u_int32_t *opnop, u_int32_t *seqnop,
+    u_char **bufferp, size_t *lenp)
+{
+
+	return (lcs_recvrpc_internal(lchp, opnop, seqnop, bufferp, lenp,
+	    NULL, NULL));
+}
+
+int
+lcs_recvrpc_rights(struct lc_host *lchp, u_int32_t *opnop, u_int32_t *seqnop,
+    u_char **bufferp, size_t *lenp, int *fdp, int *fdcountp)
+{
+
+	return (lcs_recvrpc_internal(lchp, opnop, seqnop, bufferp, lenp,
+	    fdp, fdcountp));
+}
+
+static int
+lcs_sendrpc_internal(struct lc_host *lchp, u_int32_t opno, u_int32_t seqno,
+    struct iovec *rep, int repcount, int *fdp, int fdcount)
 {
 	struct lcrpc_reply_hdr rep_hdr;
 	ssize_t len;
@@ -170,7 +208,11 @@
 	/*
 	 * Send our header.
 	 */
-	len = lcs_send(lchp, &rep_hdr, sizeof(rep_hdr), 0);
+	if (fdp != NULL)
+		len = lcs_send_rights(lchp, &rep_hdr, sizeof(rep_hdr), 0,
+		    fdp, fdcount);
+	else
+		len = lcs_send(lchp, &rep_hdr, sizeof(rep_hdr), 0);
 	if (len < 0)
 		return (-1);
 	if (len != sizeof(rep_hdr)) {
@@ -192,3 +234,21 @@
 	}
 	return (0);
 }
+
+int
+lcs_sendrpc(struct lc_host *lchp, u_int32_t opno, u_int32_t seqno,
+    struct iovec *rep, int repcount)
+{
+
+	return (lcs_sendrpc_internal(lchp, opno, seqno, rep, repcount, NULL,
+	    0));
+}
+
+int
+lcs_sendrpc_rights(struct lc_host *lchp, u_int32_t opno, u_int32_t seqno,
+    struct iovec *rep, int repcount, int *fdp, int fdcount)
+{
+
+	return (lcs_sendrpc_internal(lchp, opno, seqno, rep, repcount, fdp,
+	    fdcount));
+}


More information about the p4-projects mailing list