From owner-p4-projects@FreeBSD.ORG Mon Jun 15 09:12:20 2009 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 66B1D106571A; Mon, 15 Jun 2009 09:12:20 +0000 (UTC) Delivered-To: perforce@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 23F161065718 for ; Mon, 15 Jun 2009 09:12:20 +0000 (UTC) (envelope-from bb+lists.freebsd.perforce@cyrus.watson.org) Received: from repoman.freebsd.org (repoman.freebsd.org [IPv6:2001:4f8:fff6::29]) by mx1.freebsd.org (Postfix) with ESMTP id 0E8B48FC18 for ; Mon, 15 Jun 2009 09:12:20 +0000 (UTC) (envelope-from bb+lists.freebsd.perforce@cyrus.watson.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.14.3/8.14.3) with ESMTP id n5F9CJOD042834 for ; Mon, 15 Jun 2009 09:12:19 GMT (envelope-from bb+lists.freebsd.perforce@cyrus.watson.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.14.3/8.14.3/Submit) id n5F9CJin042832 for perforce@freebsd.org; Mon, 15 Jun 2009 09:12:19 GMT (envelope-from bb+lists.freebsd.perforce@cyrus.watson.org) Date: Mon, 15 Jun 2009 09:12:19 GMT Message-Id: <200906150912.n5F9CJin042832@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to bb+lists.freebsd.perforce@cyrus.watson.org using -f From: Robert Watson To: Perforce Change Reviews Cc: Subject: PERFORCE change 164408 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 15 Jun 2009 09:12:21 -0000 http://perforce.freebsd.org/chv.cgi?CH=164408 Change 164408 by rwatson@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 @@ -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 @@ -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)); +}