svn commit: r315862 - head/lib/libcasper/libcasper

Robert Watson rwatson at FreeBSD.org
Thu Mar 23 14:35:22 UTC 2017


Author: rwatson
Date: Thu Mar 23 14:35:21 2017
New Revision: 315862
URL: https://svnweb.freebsd.org/changeset/base/315862

Log:
  In libcasper, prefer to send a function index or service name over the IPC
  channel to a zygote process, rather than sending a function pointer or
  service pointer.  This avoids transfering pointers between address spaces,
  which while robust in this case (due to the zygote being forked() from the
  parent) is not generally a good idea, especially in the presence of
  increasingly popular control-flow integrity and pointer protection
  mitigation schemes.  With this change, ping(8) and other sandboxed tools
  using libcasper for DNS resolution now work on architectures with tagged
  memory again.
  
  Reviewed by:	oshogbo
  MFC after:	1 week
  Sponsored by:	DARPA, AFRL

Modified:
  head/lib/libcasper/libcasper/libcasper_service.c
  head/lib/libcasper/libcasper/zygote.c
  head/lib/libcasper/libcasper/zygote.h

Modified: head/lib/libcasper/libcasper/libcasper_service.c
==============================================================================
--- head/lib/libcasper/libcasper/libcasper_service.c	Thu Mar 23 14:12:21 2017	(r315861)
+++ head/lib/libcasper/libcasper/libcasper_service.c	Thu Mar 23 14:35:21 2017	(r315862)
@@ -1,11 +1,16 @@
 /*-
  * Copyright (c) 2012 The FreeBSD Foundation
  * Copyright (c) 2015 Mariusz Zaborski <oshogbo at FreeBSD.org>
+ * Copyright (c) 2017 Robert N. M. Watson
  * All rights reserved.
  *
  * This software was developed by Pawel Jakub Dawidek under sponsorship from
  * the FreeBSD Foundation.
  *
+ * This software was developed by SRI International and the University of
+ * Cambridge Computer Laboratory under DARPA/AFRL contract (FA8750-10-C-0237)
+ * ("CTSRD"), as part of the DARPA CRASH research programme.
+ *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  * are met:
@@ -130,18 +135,25 @@ casper_limit(const nvlist_t *oldlimits, 
 	return (0);
 }
 
-static void
+void
 service_execute(int chanfd)
 {
+	struct casper_service *casserv;
 	struct service *service;
+	const char *servname;
 	nvlist_t *nvl;
 	int procfd;
 
 	nvl = nvlist_recv(chanfd, 0);
 	if (nvl == NULL)
 		exit(1);
-	service = (struct service *)(uintptr_t)nvlist_take_number(nvl,
-	    "service");
+	if (!nvlist_exists_string(nvl, "service"))
+		exit(1);
+	servname = nvlist_get_string(nvl, "service");
+	casserv = service_find(servname);
+	if (casserv == NULL)
+		exit(1);
+	service = casserv->cs_service;
 	procfd = nvlist_take_descriptor(nvl, "procfd");
 	nvlist_destroy(nvl);
 
@@ -172,12 +184,11 @@ casper_command(const char *cmd, const nv
 	if (!casper_allowed_service(limits, servname))
 		return (ENOTCAPABLE);
 
-	if (zygote_clone(service_execute, &chanfd, &procfd) == -1)
+	if (zygote_clone_service_execute(&chanfd, &procfd) == -1)
 		return (errno);
 
 	nvl = nvlist_create(0);
-	nvlist_add_number(nvl, "service",
-	    (uint64_t)(uintptr_t)casserv->cs_service);
+	nvlist_add_string(nvl, "service", servname);
 	nvlist_move_descriptor(nvl, "procfd", procfd);
 	if (nvlist_send(chanfd, nvl) == -1) {
 		error = errno;

Modified: head/lib/libcasper/libcasper/zygote.c
==============================================================================
--- head/lib/libcasper/libcasper/zygote.c	Thu Mar 23 14:12:21 2017	(r315861)
+++ head/lib/libcasper/libcasper/zygote.c	Thu Mar 23 14:35:21 2017	(r315862)
@@ -1,11 +1,16 @@
 /*-
  * Copyright (c) 2012 The FreeBSD Foundation
  * Copyright (c) 2015 Mariusz Zaborski <oshogbo at FreeBSD.org>
- * All rights reserved.
+ * Copyright (c) 2017 Robert N. M. Watson
  *
  * This software was developed by Pawel Jakub Dawidek under sponsorship from
  * the FreeBSD Foundation.
  *
+ * All rights reserved.
+ * This software was developed by SRI International and the University of
+ * Cambridge Computer Laboratory under DARPA/AFRL contract (FA8750-10-C-0237)
+ * ("CTSRD"), as part of the DARPA CRASH research programme.
+ *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  * are met:
@@ -50,8 +55,10 @@ __FBSDID("$FreeBSD$");
 /* Zygote info. */
 static int	zygote_sock = -1;
 
+#define	ZYGOTE_SERVICE_EXECUTE	1
+
 int
-zygote_clone(zygote_func_t *func, int *chanfdp, int *procfdp)
+zygote_clone(uint64_t funcidx, int *chanfdp, int *procfdp)
 {
 	nvlist_t *nvl;
 	int error;
@@ -63,7 +70,7 @@ zygote_clone(zygote_func_t *func, int *c
 	}
 
 	nvl = nvlist_create(0);
-	nvlist_add_number(nvl, "func", (uint64_t)(uintptr_t)func);
+	nvlist_add_number(nvl, "funcidx", funcidx);
 	nvl = nvlist_xfer(zygote_sock, nvl, 0);
 	if (nvl == NULL)
 		return (-1);
@@ -81,6 +88,13 @@ zygote_clone(zygote_func_t *func, int *c
 	return (0);
 }
 
+int
+zygote_clone_service_execute(int *chanfdp, int *procfdp)
+{
+
+	return (zygote_clone(ZYGOTE_SERVICE_EXECUTE, chanfdp, procfdp));
+}
+
 /*
  * This function creates sandboxes on-demand whoever has access to it via
  * 'sock' socket. Function sends two descriptors to the caller: process
@@ -93,6 +107,7 @@ zygote_main(int sock)
 	int error, procfd;
 	int chanfd[2];
 	nvlist_t *nvlin, *nvlout;
+	uint64_t funcidx;
 	zygote_func_t *func;
 	pid_t pid;
 
@@ -109,10 +124,17 @@ zygote_main(int sock)
 			}
 			continue;
 		}
-		func = (zygote_func_t *)(uintptr_t)nvlist_get_number(nvlin,
-		    "func");
+		funcidx = nvlist_get_number(nvlin, "funcidx");
 		nvlist_destroy(nvlin);
 
+		switch (funcidx) {
+		case ZYGOTE_SERVICE_EXECUTE:
+			func = service_execute;
+			break;
+		default:
+			exit(0);
+		}
+
 		/*
 		 * Someone is requesting a new process, create one.
 		 */

Modified: head/lib/libcasper/libcasper/zygote.h
==============================================================================
--- head/lib/libcasper/libcasper/zygote.h	Thu Mar 23 14:12:21 2017	(r315861)
+++ head/lib/libcasper/libcasper/zygote.h	Thu Mar 23 14:35:21 2017	(r315862)
@@ -36,6 +36,12 @@
 typedef void zygote_func_t(int);
 
 int	zygote_init(void);
-int	zygote_clone(zygote_func_t *func, int *chanfdp, int *procfdp);
+int	zygote_clone(uint64_t funcidx, int *chanfdp, int *procfdp);
+int	zygote_clone_service_execute(int *chanfdp, int *procfdp);
+
+/*
+ * Functions reachable via zygote_clone().
+ */
+zygote_func_t	service_execute;
 
 #endif	/* !_ZYGOTE_H_ */


More information about the svn-src-all mailing list