Date: Thu, 23 Mar 2017 14:35:21 +0000 (UTC) From: Robert Watson <rwatson@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r315862 - head/lib/libcasper/libcasper Message-ID: <201703231435.v2NEZLEl050244@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
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@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@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_ */
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201703231435.v2NEZLEl050244>