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