diff options
author | Damien Miller <djm@mindrot.org> | 2006-08-31 03:24:41 +1000 |
---|---|---|
committer | Damien Miller <djm@mindrot.org> | 2006-08-31 03:24:41 +1000 |
commit | 1b06dc30ad4692ec76c476d130ba7366f7ebfef2 (patch) | |
tree | 85a3f1df0e15d7da1939df14a43a35dc4380a001 /openbsd-compat/port-solaris.c | |
parent | 26d4e19caa3013f57dc3c1462847eceaac6a1d7d (diff) |
- (djm) [CREDITS LICENCE Makefile.in auth.c configure.ac includes.h ]
[platform.c platform.h sshd.c openbsd-compat/Makefile.in]
[openbsd-compat/openbsd-compat.h openbsd-compat/port-solaris.c]
[openbsd-compat/port-solaris.h] Add support for Solaris process
contracts, enabled with --use-solaris-contracts. Patch from Chad
Mynhier, tweaked by dtucker@ and myself; ok dtucker@
Diffstat (limited to 'openbsd-compat/port-solaris.c')
-rw-r--r-- | openbsd-compat/port-solaris.c | 189 |
1 files changed, 189 insertions, 0 deletions
diff --git a/openbsd-compat/port-solaris.c b/openbsd-compat/port-solaris.c new file mode 100644 index 00000000..f31f0c6e --- /dev/null +++ b/openbsd-compat/port-solaris.c @@ -0,0 +1,189 @@ +/* $Id: port-solaris.c,v 1.1 2006/08/30 17:24:42 djm Exp $ */ + +/* + * Copyright (c) 2006 Chad Mynhier. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include "config.h" +#include "includes.h" + +#ifdef USE_SOLARIS_PROCESS_CONTRACTS + +#include <sys/types.h> +#include <sys/stat.h> +#include <sys/param.h> + +#include <errno.h> +#ifdef HAVE_FCNTL_H +# include <fcntl.h> +#endif +#include <string.h> +#include <unistd.h> + +#include <libcontract.h> +#include <sys/contract/process.h> +#include <sys/ctfs.h> + +#include "log.h" + +#define CT_TEMPLATE CTFS_ROOT "/process/template" +#define CT_LATEST CTFS_ROOT "/process/latest" + +static int tmpl_fd = -1; + +/* Lookup the latest process contract */ +static ctid_t +get_active_process_contract_id(void) +{ + int stat_fd; + ctid_t ctid = -1; + ct_stathdl_t stathdl; + + if ((stat_fd = open64(CT_LATEST, O_RDONLY)) == -1) { + error("%s: Error opening 'latest' process " + "contract: %s", __func__, strerror(errno)); + return -1; + } + if (ct_status_read(stat_fd, CTD_COMMON, &stathdl) != 0) { + error("%s: Error reading process contract " + "status: %s", __func__, strerror(errno)); + goto out; + } + if ((ctid = ct_status_get_id(stathdl)) < 0) { + error("%s: Error getting process contract id: %s", + __func__, strerror(errno)); + goto out; + } + + ct_status_free(stathdl); + out: + close(stat_fd); + return ctid; +} + +void +solaris_contract_pre_fork(void) +{ + if ((tmpl_fd = open64(CT_TEMPLATE, O_RDWR)) == -1) { + error("%s: open %s: %s", __func__, + CT_TEMPLATE, strerror(errno)); + return; + } + + debug2("%s: setting up process contract template on fd %d", + __func__, tmpl_fd); + + /* We have to set certain attributes before activating the template */ + if (ct_pr_tmpl_set_fatal(tmpl_fd, + CT_PR_EV_HWERR|CT_PR_EV_SIGNAL|CT_PR_EV_CORE) != 0) { + error("%s: Error setting process contract template " + "fatal events: %s", __func__, strerror(errno)); + goto fail; + } + if (ct_tmpl_set_critical(tmpl_fd, CT_PR_EV_HWERR) != 0) { + error("%s: Error setting process contract template " + "critical events: %s", __func__, strerror(errno)); + goto fail; + } + + /* Now make this the active template for this process. */ + if (ct_tmpl_activate(tmpl_fd) != 0) { + error("%s: Error activating process contract " + "template: %s", __func__, strerror(errno)); + goto fail; + } + return; + + fail: + if (tmpl_fd != -1) { + close(tmpl_fd); + tmpl_fd = -1; + } +} + +void +solaris_contract_post_fork_child() +{ + debug2("%s: clearing process contract template on fd %d", + __func__, tmpl_fd); + + /* Clear the active template. */ + if (ct_tmpl_clear(tmpl_fd) != 0) + error("%s: Error clearing active process contract " + "template: %s", __func__, strerror(errno)); + + close(tmpl_fd); + tmpl_fd = -1; +} + +void +solaris_contract_post_fork_parent(pid_t pid) +{ + ctid_t ctid; + char ctl_path[256]; + int r, ctl_fd = -1, stat_fd = -1; + + debug2("%s: clearing template (fd %d)", __func__, tmpl_fd); + + if (tmpl_fd == -1) + return; + + /* First clear the active template. */ + if ((r = ct_tmpl_clear(tmpl_fd)) != 0) + error("%s: Error clearing active process contract " + "template: %s", __func__, strerror(errno)); + + close(tmpl_fd); + tmpl_fd = -1; + + /* + * If either the fork didn't succeed (pid < 0), or clearing + * th active contract failed (r != 0), then we have nothing + * more do. + */ + if (r != 0 || pid <= 0) + return; + + /* Now lookup and abandon the contract we've created. */ + ctid = get_active_process_contract_id(); + + debug2("%s: abandoning contract id %ld", __func__, ctid); + + snprintf(ctl_path, sizeof(ctl_path), + CTFS_ROOT "/process/%ld/ctl", ctid); + if ((ctl_fd = open64(ctl_path, O_WRONLY)) < 0) { + error("%s: Error opening process contract " + "ctl file: %s", __func__, strerror(errno)); + goto fail; + } + if (ct_ctl_abandon(ctl_fd) < 0) { + error("%s: Error abandoning process contract: %s", + __func__, strerror(errno)); + goto fail; + } + close(ctl_fd); + return; + + fail: + if (tmpl_fd != -1) { + close(tmpl_fd); + tmpl_fd = -1; + } + if (stat_fd != -1) + close(stat_fd); + if (ctl_fd != -1) + close(ctl_fd); +} +#endif |