1255708Sjhb/*- 2255708Sjhb * Copyright (c) 2013 Advanced Computing Technologies LLC 3255708Sjhb * Written by: John H. Baldwin <jhb@FreeBSD.org> 4255708Sjhb * All rights reserved. 5255708Sjhb * 6255708Sjhb * Redistribution and use in source and binary forms, with or without 7255708Sjhb * modification, are permitted provided that the following conditions 8255708Sjhb * are met: 9255708Sjhb * 1. Redistributions of source code must retain the above copyright 10255708Sjhb * notice, this list of conditions and the following disclaimer. 11255708Sjhb * 2. Redistributions in binary form must reproduce the above copyright 12255708Sjhb * notice, this list of conditions and the following disclaimer in the 13255708Sjhb * documentation and/or other materials provided with the distribution. 14255708Sjhb * 15255708Sjhb * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 16255708Sjhb * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17255708Sjhb * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18255708Sjhb * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 19255708Sjhb * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20255708Sjhb * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21255708Sjhb * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22255708Sjhb * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23255708Sjhb * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24255708Sjhb * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25255708Sjhb * SUCH DAMAGE. 26255708Sjhb */ 27255708Sjhb 28255708Sjhb#include <sys/cdefs.h> 29255708Sjhb__FBSDID("$FreeBSD$"); 30255708Sjhb 31255708Sjhb#include <sys/procctl.h> 32255708Sjhb#include <sys/types.h> 33255708Sjhb#include <sys/mman.h> 34255708Sjhb#include <err.h> 35255708Sjhb#include <errno.h> 36255708Sjhb#include <stdbool.h> 37255708Sjhb#include <stdio.h> 38255708Sjhb#include <stdlib.h> 39255708Sjhb#include <unistd.h> 40255708Sjhb 41255708Sjhbstatic void 42255708Sjhbusage(void) 43255708Sjhb{ 44255708Sjhb 45255708Sjhb fprintf(stderr, "usage: protect [-i] command\n"); 46255708Sjhb fprintf(stderr, " protect [-cdi] -g pgrp | -p pid\n"); 47255708Sjhb exit(1); 48255708Sjhb} 49255708Sjhb 50255708Sjhbstatic id_t 51255708Sjhbparse_id(char *id) 52255708Sjhb{ 53255708Sjhb static bool first = true; 54255708Sjhb long value; 55255708Sjhb char *ch; 56255708Sjhb 57255708Sjhb if (!first) { 58255708Sjhb warnx("only one -g or -p flag is permitted"); 59255708Sjhb usage(); 60255708Sjhb } 61255708Sjhb value = strtol(id, &ch, 0); 62255708Sjhb if (*ch != '\0') { 63255708Sjhb warnx("invalid process id"); 64255708Sjhb usage(); 65255708Sjhb } 66255708Sjhb return (value); 67255708Sjhb} 68255708Sjhb 69255708Sjhbint 70255708Sjhbmain(int argc, char *argv[]) 71255708Sjhb{ 72255708Sjhb idtype_t idtype; 73255708Sjhb id_t id; 74255708Sjhb int ch, flags; 75255708Sjhb bool descend, inherit, idset; 76255708Sjhb 77255708Sjhb idtype = P_PID; 78255708Sjhb id = getpid(); 79255708Sjhb flags = PPROT_SET; 80255708Sjhb descend = inherit = idset = false; 81255708Sjhb while ((ch = getopt(argc, argv, "cdig:p:")) != -1) 82255708Sjhb switch (ch) { 83255708Sjhb case 'c': 84255708Sjhb flags = PPROT_CLEAR; 85255708Sjhb break; 86255708Sjhb case 'd': 87255708Sjhb descend = true; 88255708Sjhb break; 89255708Sjhb case 'i': 90255708Sjhb inherit = true; 91255708Sjhb break; 92255708Sjhb case 'g': 93255708Sjhb idtype = P_PGID; 94255708Sjhb id = parse_id(optarg); 95255708Sjhb idset = true; 96255708Sjhb break; 97255708Sjhb case 'p': 98255708Sjhb idtype = P_PID; 99255708Sjhb id = parse_id(optarg); 100255708Sjhb idset = true; 101255708Sjhb break; 102255708Sjhb } 103255708Sjhb argc -= optind; 104255708Sjhb argv += optind; 105255708Sjhb 106255708Sjhb if ((idset && argc != 0) || (!idset && (argc == 0 || descend))) 107255708Sjhb usage(); 108255708Sjhb 109255708Sjhb if (descend) 110255708Sjhb flags |= PPROT_DESCEND; 111255708Sjhb if (inherit) 112255708Sjhb flags |= PPROT_INHERIT; 113255708Sjhb if (procctl(idtype, id, PROC_SPROTECT, &flags) == -1) 114255708Sjhb err(1, "procctl"); 115255708Sjhb 116255708Sjhb if (argc != 0) { 117255708Sjhb errno = 0; 118255708Sjhb execvp(*argv, argv); 119255708Sjhb err(errno == ENOENT ? 127 : 126, "%s", *argv); 120255708Sjhb } 121255708Sjhb return (0); 122255708Sjhb} 123