PERFORCE change 164654 for review

Robert Watson rwatson at FreeBSD.org
Thu Jun 18 10:57:19 UTC 2009


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

Change 164654 by rwatson at rwatson_freebsd_capabilities on 2009/06/18 10:56:22

	Sandbox bzip2 decompression in gzip(1).

Affected files ...

.. //depot/projects/trustedbsd/capabilities/src/usr.bin/gzip/gzip.c#6 edit
.. //depot/projects/trustedbsd/capabilities/src/usr.bin/gzip/gzip.h#2 edit
.. //depot/projects/trustedbsd/capabilities/src/usr.bin/gzip/gzsandbox.c#3 edit
.. //depot/projects/trustedbsd/capabilities/src/usr.bin/gzip/unbzip2.c#3 edit

Differences ...

==== //depot/projects/trustedbsd/capabilities/src/usr.bin/gzip/gzip.c#6 (text+ko) ====

@@ -239,10 +239,6 @@
 static	int	check_outfile(const char *outfile);
 #endif
 
-#ifndef NO_BZIP2_SUPPORT
-static	off_t	unbzip2(int, int, char *, size_t, off_t *);
-#endif
-
 #ifndef NO_COMPRESS_SUPPORT
 static	FILE 	*zdopen(int);
 static	off_t	zuncompress(FILE *, FILE *, char *, size_t, off_t *);
@@ -1417,7 +1413,7 @@
 			goto lose;
 		}
 
-		size = unbzip2(fd, zfd, NULL, 0, NULL);
+		size = unbzip2_wrapper(fd, zfd, NULL, 0, NULL);
 	} else
 #endif
 
@@ -1636,7 +1632,7 @@
 		break;
 #ifndef NO_BZIP2_SUPPORT
 	case FT_BZIP2:
-		usize = unbzip2(STDIN_FILENO, STDOUT_FILENO,
+		usize = unbzip2_wrapper(STDIN_FILENO, STDOUT_FILENO,
 				(char *)header1, sizeof header1, &gsize);
 		break;
 #endif

==== //depot/projects/trustedbsd/capabilities/src/usr.bin/gzip/gzip.h#2 (text+ko) ====

@@ -42,5 +42,8 @@
 	    off_t *gsizep, const char *filename);
 off_t	gz_uncompress_wrapper(int in, int out, char *pre, size_t prelen,
 	    off_t *gsizep, const char *filename);
+off_t	unbzip2(int in, int out, char *pre, size_t prelen, off_t *bytes_in);
+off_t	unbzip2_wrapper(int in, int out, char *pre, size_t prelen,
+	    off_t *bytes_in);
 
 #endif /* !_GZIP_H_ */

==== //depot/projects/trustedbsd/capabilities/src/usr.bin/gzip/gzsandbox.c#3 (text+ko) ====

@@ -54,6 +54,7 @@
 
 #define	PROXIED_GZ_COMPRESS	1
 #define	PROXIED_GZ_UNCOMPRESS	2
+#define	PROXIED_UNBZIP2		3
 
 static struct lc_sandbox	*lcsp;
 static int			 gzsandbox_initialized;
@@ -243,6 +244,88 @@
 		    filename));
 }
 
+struct host_unbzip2_req {
+	size_t	hub_req_prelen;
+	/* ... followed by data ... */
+};
+
+struct host_unbzip2_rep {
+	off_t	hub_rep_bytes_in;
+	off_t	hub_rep_retval;
+};
+
+static off_t
+unbzip2_insandbox(int in, int out, char *pre, size_t prelen, off_t *bytes_in)
+{
+	struct host_unbzip2_req req;
+	struct host_unbzip2_rep rep;
+	struct iovec iov_req[2], iov_rep;
+	int fdarray[2];
+	size_t len;
+
+	if (lcsp == NULL) {
+		if (lch_start_flags(LC_USR_BIN_GZIP_SANDBOX, lc_sandbox_argv,
+		    LCH_PERMIT_STDERR, &lcsp) < 0)
+			err(-1, "lch_start %s", LC_USR_BIN_GZIP_SANDBOX);
+	}
+
+	bzero(&req, sizeof(req));
+	req.hub_req_prelen = prelen;
+	iov_req[0].iov_base = &req;
+	iov_req[0].iov_len = sizeof(req);
+	iov_req[1].iov_base = pre;
+	iov_req[1].iov_len = prelen;
+	iov_rep.iov_base = &rep;
+	iov_rep.iov_len = sizeof(rep);
+	fdarray[0] = cap_new(in, CAP_FSTAT | CAP_READ | CAP_SEEK);
+	fdarray[1] = cap_new(out, CAP_FSTAT | CAP_WRITE | CAP_SEEK);
+	if (fdarray[0] == -1 || fdarray[1] == -1)
+		err(-1, "cap_new");
+	if (lch_rpc_rights(lcsp, PROXIED_UNBZIP2, iov_req, 1,
+	    fdarray, 2, &iov_rep, 1, &len, NULL, NULL) < 0)
+		err(-1, "lch_rpc_rights");
+	if (len != sizeof(rep))
+		errx(-1, "lch_rpc_rights len %d", len);
+	if (bytes_in != NULL)
+		*bytes_in = rep.hub_rep_bytes_in;
+	close(fdarray[0]);
+	close(fdarray[1]);
+	return (rep.hub_rep_retval);
+}
+
+static void
+sandbox_unbzip2_buffer(struct lc_host *lchp, uint32_t opno,
+    uint32_t seqno, char *buffer, size_t len, int fd_in, int fd_out)
+{
+	struct host_unbzip2_req req;
+	struct host_unbzip2_rep rep;
+	struct iovec iov;
+	char *pre;
+
+	if (len != sizeof(req))
+		err(-1, "sandbox_gz_uncompress_buffer: len %d", len);
+
+	bcopy(buffer, &req, sizeof(req));
+	pre = buffer + sizeof(req);
+	bzero(&rep, sizeof(rep));
+	rep.hub_rep_retval = unbzip2(fd_in, fd_out, pre, req.hub_req_prelen,
+	    &rep.hub_rep_bytes_in);
+	iov.iov_base = &rep;
+	iov.iov_len = sizeof(rep);
+	if (lcs_sendrpc(lchp, opno, seqno, &iov, 1) < 0)
+		err(-1, "lcs_sendrpc");
+}
+off_t
+unbzip2_wrapper(int in, int out, char *pre, size_t prelen, off_t *bytes_in)
+{
+
+	if (!gzsandbox_initialized)
+		gzsandbox_initialize();
+	if (gzsandbox_enabled)
+		return (unbzip2_insandbox(in, out, pre, prelen, bytes_in));
+	else
+		return (unbzip2(in, out, pre, prelen, bytes_in));
+}
 
 int
 cap_main(__unused int argc, __unused char *argv[])
@@ -284,6 +367,15 @@
 			close(fdarray[1]);
 			break;
 
+		case PROXIED_UNBZIP2:
+			if (fdcount != 2)
+				errx(-1, "sandbox_workloop: %d fds", fdcount);
+			sandbox_unbzip2_buffer(lchp, opno, seqno, buffer, len,
+			    fdarray[0], fdarray[1]);
+			close(fdarray[0]);
+			close(fdarray[1]);
+			break;
+
 		default:
 			errx(-1, "sandbox_workloop: unknown op %d", opno);
 		}

==== //depot/projects/trustedbsd/capabilities/src/usr.bin/gzip/unbzip2.c#3 (text+ko) ====

@@ -33,7 +33,7 @@
 
 /* This file is #included by gzip.c */
 
-static off_t
+off_t
 unbzip2(int in, int out, char *pre, size_t prelen, off_t *bytes_in)
 {
 	int		ret, end_of_file;


More information about the p4-projects mailing list