diff --git a/lib/libcasper/libcasper/libcasper_service.c b/lib/libcasper/libcasper/libcasper_service.c index 1f9e8d6fcd76..ae20b8cd18f9 100644 --- a/lib/libcasper/libcasper/libcasper_service.c +++ b/lib/libcasper/libcasper/libcasper_service.c @@ -1,11 +1,16 @@ /*- * Copyright (c) 2012 The FreeBSD Foundation * Copyright (c) 2015 Mariusz Zaborski + * 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, const nvlist_t *newlimits) 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 nvlist_t *limits, nvlist_t *nvlin, 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; diff --git a/lib/libcasper/libcasper/zygote.c b/lib/libcasper/libcasper/zygote.c index feeb1537af87..02ddfd003c29 100644 --- a/lib/libcasper/libcasper/zygote.c +++ b/lib/libcasper/libcasper/zygote.c @@ -1,11 +1,16 @@ /*- * Copyright (c) 2012 The FreeBSD Foundation * Copyright (c) 2015 Mariusz Zaborski - * 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 *chanfdp, int *procfdp) } 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 *chanfdp, int *procfdp) 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. */ diff --git a/lib/libcasper/libcasper/zygote.h b/lib/libcasper/libcasper/zygote.h index e147287e1dbc..69200a383d48 100644 --- a/lib/libcasper/libcasper/zygote.h +++ b/lib/libcasper/libcasper/zygote.h @@ -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_ */