155648840SJohn Baldwin /*-
2*4d846d26SWarner Losh * SPDX-License-Identifier: BSD-2-Clause
31de7b4b8SPedro F. Giffuni *
4179fa75eSJohn Baldwin * Copyright (c) 2013 Hudson River Trading LLC
555648840SJohn Baldwin * Written by: John H. Baldwin <jhb@FreeBSD.org>
655648840SJohn Baldwin * All rights reserved.
755648840SJohn Baldwin *
855648840SJohn Baldwin * Redistribution and use in source and binary forms, with or without
955648840SJohn Baldwin * modification, are permitted provided that the following conditions
1055648840SJohn Baldwin * are met:
1155648840SJohn Baldwin * 1. Redistributions of source code must retain the above copyright
1255648840SJohn Baldwin * notice, this list of conditions and the following disclaimer.
1355648840SJohn Baldwin * 2. Redistributions in binary form must reproduce the above copyright
1455648840SJohn Baldwin * notice, this list of conditions and the following disclaimer in the
1555648840SJohn Baldwin * documentation and/or other materials provided with the distribution.
1655648840SJohn Baldwin *
1755648840SJohn Baldwin * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
1855648840SJohn Baldwin * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1955648840SJohn Baldwin * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2055648840SJohn Baldwin * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
2155648840SJohn Baldwin * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2255648840SJohn Baldwin * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2355648840SJohn Baldwin * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2455648840SJohn Baldwin * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2555648840SJohn Baldwin * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2655648840SJohn Baldwin * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2755648840SJohn Baldwin * SUCH DAMAGE.
2855648840SJohn Baldwin */
2955648840SJohn Baldwin
3055648840SJohn Baldwin #include <sys/cdefs.h>
3155648840SJohn Baldwin #include <sys/procctl.h>
3255648840SJohn Baldwin #include <sys/types.h>
3355648840SJohn Baldwin #include <sys/mman.h>
3455648840SJohn Baldwin #include <err.h>
3555648840SJohn Baldwin #include <errno.h>
3655648840SJohn Baldwin #include <stdbool.h>
3755648840SJohn Baldwin #include <stdio.h>
3855648840SJohn Baldwin #include <stdlib.h>
3955648840SJohn Baldwin #include <unistd.h>
4055648840SJohn Baldwin
4155648840SJohn Baldwin static void
usage(void)4255648840SJohn Baldwin usage(void)
4355648840SJohn Baldwin {
4455648840SJohn Baldwin
4555648840SJohn Baldwin fprintf(stderr, "usage: protect [-i] command\n");
4655648840SJohn Baldwin fprintf(stderr, " protect [-cdi] -g pgrp | -p pid\n");
4755648840SJohn Baldwin exit(1);
4855648840SJohn Baldwin }
4955648840SJohn Baldwin
5055648840SJohn Baldwin static id_t
parse_id(char * id)5155648840SJohn Baldwin parse_id(char *id)
5255648840SJohn Baldwin {
5355648840SJohn Baldwin static bool first = true;
5455648840SJohn Baldwin long value;
5555648840SJohn Baldwin char *ch;
5655648840SJohn Baldwin
5755648840SJohn Baldwin if (!first) {
5855648840SJohn Baldwin warnx("only one -g or -p flag is permitted");
5955648840SJohn Baldwin usage();
6055648840SJohn Baldwin }
6155648840SJohn Baldwin value = strtol(id, &ch, 0);
6255648840SJohn Baldwin if (*ch != '\0') {
6355648840SJohn Baldwin warnx("invalid process id");
6455648840SJohn Baldwin usage();
6555648840SJohn Baldwin }
6655648840SJohn Baldwin return (value);
6755648840SJohn Baldwin }
6855648840SJohn Baldwin
6955648840SJohn Baldwin int
main(int argc,char * argv[])7055648840SJohn Baldwin main(int argc, char *argv[])
7155648840SJohn Baldwin {
7255648840SJohn Baldwin idtype_t idtype;
7355648840SJohn Baldwin id_t id;
7455648840SJohn Baldwin int ch, flags;
7555648840SJohn Baldwin bool descend, inherit, idset;
7655648840SJohn Baldwin
7755648840SJohn Baldwin idtype = P_PID;
7855648840SJohn Baldwin id = getpid();
7955648840SJohn Baldwin flags = PPROT_SET;
8055648840SJohn Baldwin descend = inherit = idset = false;
8155648840SJohn Baldwin while ((ch = getopt(argc, argv, "cdig:p:")) != -1)
8255648840SJohn Baldwin switch (ch) {
8355648840SJohn Baldwin case 'c':
8455648840SJohn Baldwin flags = PPROT_CLEAR;
8555648840SJohn Baldwin break;
8655648840SJohn Baldwin case 'd':
8755648840SJohn Baldwin descend = true;
8855648840SJohn Baldwin break;
8955648840SJohn Baldwin case 'i':
9055648840SJohn Baldwin inherit = true;
9155648840SJohn Baldwin break;
9255648840SJohn Baldwin case 'g':
9355648840SJohn Baldwin idtype = P_PGID;
9455648840SJohn Baldwin id = parse_id(optarg);
9555648840SJohn Baldwin idset = true;
9655648840SJohn Baldwin break;
9755648840SJohn Baldwin case 'p':
9855648840SJohn Baldwin idtype = P_PID;
9955648840SJohn Baldwin id = parse_id(optarg);
10055648840SJohn Baldwin idset = true;
10155648840SJohn Baldwin break;
10255648840SJohn Baldwin }
10355648840SJohn Baldwin argc -= optind;
10455648840SJohn Baldwin argv += optind;
10555648840SJohn Baldwin
10655648840SJohn Baldwin if ((idset && argc != 0) || (!idset && (argc == 0 || descend)))
10755648840SJohn Baldwin usage();
10855648840SJohn Baldwin
10955648840SJohn Baldwin if (descend)
11055648840SJohn Baldwin flags |= PPROT_DESCEND;
11155648840SJohn Baldwin if (inherit)
11255648840SJohn Baldwin flags |= PPROT_INHERIT;
11355648840SJohn Baldwin if (procctl(idtype, id, PROC_SPROTECT, &flags) == -1)
11455648840SJohn Baldwin err(1, "procctl");
11555648840SJohn Baldwin
11655648840SJohn Baldwin if (argc != 0) {
11755648840SJohn Baldwin errno = 0;
11855648840SJohn Baldwin execvp(*argv, argv);
11955648840SJohn Baldwin err(errno == ENOENT ? 127 : 126, "%s", *argv);
12055648840SJohn Baldwin }
12155648840SJohn Baldwin return (0);
12255648840SJohn Baldwin }
123