xref: /freebsd/usr.bin/proccontrol/proccontrol.c (revision acb1f1269c6f4ff89a0d28ba742f6687e9ef779d)
17402f93eSKonstantin Belousov /*-
27402f93eSKonstantin Belousov  * Copyright (c) 2016 The FreeBSD Foundation
37402f93eSKonstantin Belousov  * All rights reserved.
47402f93eSKonstantin Belousov  *
57402f93eSKonstantin Belousov  * This software was developed by Konstantin Belousov <kib@FreeBSD.org>
67402f93eSKonstantin Belousov  * under sponsorship from the FreeBSD Foundation.
77402f93eSKonstantin Belousov  *
87402f93eSKonstantin Belousov  * Redistribution and use in source and binary forms, with or without
97402f93eSKonstantin Belousov  * modification, are permitted provided that the following conditions
107402f93eSKonstantin Belousov  * are met:
117402f93eSKonstantin Belousov  * 1. Redistributions of source code must retain the above copyright
127402f93eSKonstantin Belousov  *    notice, this list of conditions and the following disclaimer.
137402f93eSKonstantin Belousov  * 2. Redistributions in binary form must reproduce the above copyright
147402f93eSKonstantin Belousov  *    notice, this list of conditions and the following disclaimer in the
157402f93eSKonstantin Belousov  *    documentation and/or other materials provided with the distribution.
167402f93eSKonstantin Belousov  *
177402f93eSKonstantin Belousov  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
187402f93eSKonstantin Belousov  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
197402f93eSKonstantin Belousov  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
207402f93eSKonstantin Belousov  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
217402f93eSKonstantin Belousov  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
227402f93eSKonstantin Belousov  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
237402f93eSKonstantin Belousov  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
247402f93eSKonstantin Belousov  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
257402f93eSKonstantin Belousov  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
267402f93eSKonstantin Belousov  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
277402f93eSKonstantin Belousov  * SUCH DAMAGE.
287402f93eSKonstantin Belousov  */
297402f93eSKonstantin Belousov 
307402f93eSKonstantin Belousov #include <sys/cdefs.h>
317402f93eSKonstantin Belousov __FBSDID("$FreeBSD$");
327402f93eSKonstantin Belousov 
337402f93eSKonstantin Belousov #include <sys/procctl.h>
347402f93eSKonstantin Belousov #include <err.h>
357402f93eSKonstantin Belousov #include <stdbool.h>
367402f93eSKonstantin Belousov #include <stdio.h>
377402f93eSKonstantin Belousov #include <stdlib.h>
387402f93eSKonstantin Belousov #include <string.h>
397402f93eSKonstantin Belousov #include <unistd.h>
407402f93eSKonstantin Belousov 
417402f93eSKonstantin Belousov enum {
42fa50a355SKonstantin Belousov 	MODE_ASLR,
437402f93eSKonstantin Belousov 	MODE_INVALID,
447402f93eSKonstantin Belousov 	MODE_TRACE,
457402f93eSKonstantin Belousov 	MODE_TRAPCAP,
4646922074SKonstantin Belousov 	MODE_PROTMAX,
47c22994e3SKonstantin Belousov 	MODE_STACKGAP,
48*acb1f126SEdward Tomasz Napierala 	MODE_NO_NEW_PRIVS,
49bab3f1d0SKonstantin Belousov #ifdef PROC_KPTI_CTL
50bab3f1d0SKonstantin Belousov 	MODE_KPTI,
51bab3f1d0SKonstantin Belousov #endif
52da477bcdSKonstantin Belousov #ifdef PROC_LA_CTL
53da477bcdSKonstantin Belousov 	MODE_LA57,
54da477bcdSKonstantin Belousov 	MODE_LA48,
55da477bcdSKonstantin Belousov #endif
567402f93eSKonstantin Belousov };
577402f93eSKonstantin Belousov 
587402f93eSKonstantin Belousov static pid_t
597402f93eSKonstantin Belousov str2pid(const char *str)
607402f93eSKonstantin Belousov {
617402f93eSKonstantin Belousov 	pid_t res;
627402f93eSKonstantin Belousov 	char *tail;
637402f93eSKonstantin Belousov 
647402f93eSKonstantin Belousov 	res = strtol(str, &tail, 0);
657402f93eSKonstantin Belousov 	if (*tail != '\0') {
667402f93eSKonstantin Belousov 		warnx("non-numeric pid");
677402f93eSKonstantin Belousov 		return (-1);
687402f93eSKonstantin Belousov 	}
697402f93eSKonstantin Belousov 	return (res);
707402f93eSKonstantin Belousov }
717402f93eSKonstantin Belousov 
72bab3f1d0SKonstantin Belousov #ifdef PROC_KPTI_CTL
73bab3f1d0SKonstantin Belousov #define	KPTI_USAGE "|kpti"
74bab3f1d0SKonstantin Belousov #else
75bab3f1d0SKonstantin Belousov #define	KPTI_USAGE
76bab3f1d0SKonstantin Belousov #endif
77da477bcdSKonstantin Belousov #ifdef PROC_LA_CTL
78da477bcdSKonstantin Belousov #define	LA_USAGE "|la48|la57"
79da477bcdSKonstantin Belousov #else
80da477bcdSKonstantin Belousov #define	LA_USAGE
81da477bcdSKonstantin Belousov #endif
82bab3f1d0SKonstantin Belousov 
837402f93eSKonstantin Belousov static void __dead2
847402f93eSKonstantin Belousov usage(void)
857402f93eSKonstantin Belousov {
867402f93eSKonstantin Belousov 
87c22994e3SKonstantin Belousov 	fprintf(stderr, "Usage: proccontrol -m (aslr|protmax|trace|trapcap|"
88*acb1f126SEdward Tomasz Napierala 	    "stackgap|nonewprivs"KPTI_USAGE LA_USAGE") [-q] "
897402f93eSKonstantin Belousov 	    "[-s (enable|disable)] [-p pid | command]\n");
907402f93eSKonstantin Belousov 	exit(1);
917402f93eSKonstantin Belousov }
927402f93eSKonstantin Belousov 
937402f93eSKonstantin Belousov int
947402f93eSKonstantin Belousov main(int argc, char *argv[])
957402f93eSKonstantin Belousov {
967402f93eSKonstantin Belousov 	int arg, ch, error, mode;
977402f93eSKonstantin Belousov 	pid_t pid;
987402f93eSKonstantin Belousov 	bool enable, do_command, query;
997402f93eSKonstantin Belousov 
1007402f93eSKonstantin Belousov 	mode = MODE_INVALID;
1017402f93eSKonstantin Belousov 	enable = true;
1027402f93eSKonstantin Belousov 	pid = -1;
1037402f93eSKonstantin Belousov 	query = false;
1047402f93eSKonstantin Belousov 	while ((ch = getopt(argc, argv, "m:qs:p:")) != -1) {
1057402f93eSKonstantin Belousov 		switch (ch) {
1067402f93eSKonstantin Belousov 		case 'm':
107fa50a355SKonstantin Belousov 			if (strcmp(optarg, "aslr") == 0)
108fa50a355SKonstantin Belousov 				mode = MODE_ASLR;
10946922074SKonstantin Belousov 			else if (strcmp(optarg, "protmax") == 0)
11046922074SKonstantin Belousov 				mode = MODE_PROTMAX;
111fa50a355SKonstantin Belousov 			else if (strcmp(optarg, "trace") == 0)
1127402f93eSKonstantin Belousov 				mode = MODE_TRACE;
1137402f93eSKonstantin Belousov 			else if (strcmp(optarg, "trapcap") == 0)
1147402f93eSKonstantin Belousov 				mode = MODE_TRAPCAP;
115c22994e3SKonstantin Belousov 			else if (strcmp(optarg, "stackgap") == 0)
116c22994e3SKonstantin Belousov 				mode = MODE_STACKGAP;
117*acb1f126SEdward Tomasz Napierala 			else if (strcmp(optarg, "nonewprivs") == 0)
118*acb1f126SEdward Tomasz Napierala 				mode = MODE_NO_NEW_PRIVS;
119bab3f1d0SKonstantin Belousov #ifdef PROC_KPTI_CTL
120bab3f1d0SKonstantin Belousov 			else if (strcmp(optarg, "kpti") == 0)
121bab3f1d0SKonstantin Belousov 				mode = MODE_KPTI;
122bab3f1d0SKonstantin Belousov #endif
123da477bcdSKonstantin Belousov #ifdef PROC_LA_CTL
124da477bcdSKonstantin Belousov 			else if (strcmp(optarg, "la57") == 0)
125da477bcdSKonstantin Belousov 				mode = MODE_LA57;
126da477bcdSKonstantin Belousov 			else if (strcmp(optarg, "la48") == 0)
127da477bcdSKonstantin Belousov 				mode = MODE_LA48;
128da477bcdSKonstantin Belousov #endif
1297402f93eSKonstantin Belousov 			else
1307402f93eSKonstantin Belousov 				usage();
1317402f93eSKonstantin Belousov 			break;
1327402f93eSKonstantin Belousov 		case 's':
1337402f93eSKonstantin Belousov 			if (strcmp(optarg, "enable") == 0)
1347402f93eSKonstantin Belousov 				enable = true;
1357402f93eSKonstantin Belousov 			else if (strcmp(optarg, "disable") == 0)
1367402f93eSKonstantin Belousov 				enable = false;
1377402f93eSKonstantin Belousov 			else
1387402f93eSKonstantin Belousov 				usage();
1397402f93eSKonstantin Belousov 			break;
1407402f93eSKonstantin Belousov 		case 'p':
1417402f93eSKonstantin Belousov 			pid = str2pid(optarg);
1427402f93eSKonstantin Belousov 			break;
1437402f93eSKonstantin Belousov 		case 'q':
1447402f93eSKonstantin Belousov 			query = true;
1457402f93eSKonstantin Belousov 			break;
1467402f93eSKonstantin Belousov 		case '?':
1477402f93eSKonstantin Belousov 		default:
1487402f93eSKonstantin Belousov 			usage();
1497402f93eSKonstantin Belousov 			break;
1507402f93eSKonstantin Belousov 		}
1517402f93eSKonstantin Belousov 	}
1527402f93eSKonstantin Belousov 	argc -= optind;
1537402f93eSKonstantin Belousov 	argv += optind;
1547402f93eSKonstantin Belousov 	do_command = argc != 0;
1557402f93eSKonstantin Belousov 	if (do_command) {
1567402f93eSKonstantin Belousov 		if (pid != -1 || query)
1577402f93eSKonstantin Belousov 			usage();
1587402f93eSKonstantin Belousov 		pid = getpid();
1597402f93eSKonstantin Belousov 	} else if (pid == -1) {
1607402f93eSKonstantin Belousov 		pid = getpid();
1617402f93eSKonstantin Belousov 	}
1627402f93eSKonstantin Belousov 
1637402f93eSKonstantin Belousov 	if (query) {
1647402f93eSKonstantin Belousov 		switch (mode) {
165fa50a355SKonstantin Belousov 		case MODE_ASLR:
166fa50a355SKonstantin Belousov 			error = procctl(P_PID, pid, PROC_ASLR_STATUS, &arg);
167fa50a355SKonstantin Belousov 			break;
1687402f93eSKonstantin Belousov 		case MODE_TRACE:
1697402f93eSKonstantin Belousov 			error = procctl(P_PID, pid, PROC_TRACE_STATUS, &arg);
1707402f93eSKonstantin Belousov 			break;
1717402f93eSKonstantin Belousov 		case MODE_TRAPCAP:
1727402f93eSKonstantin Belousov 			error = procctl(P_PID, pid, PROC_TRAPCAP_STATUS, &arg);
1737402f93eSKonstantin Belousov 			break;
17446922074SKonstantin Belousov 		case MODE_PROTMAX:
17546922074SKonstantin Belousov 			error = procctl(P_PID, pid, PROC_PROTMAX_STATUS, &arg);
17646922074SKonstantin Belousov 			break;
177c22994e3SKonstantin Belousov 		case MODE_STACKGAP:
178c22994e3SKonstantin Belousov 			error = procctl(P_PID, pid, PROC_STACKGAP_STATUS, &arg);
179c22994e3SKonstantin Belousov 			break;
180*acb1f126SEdward Tomasz Napierala 		case MODE_NO_NEW_PRIVS:
181*acb1f126SEdward Tomasz Napierala 			error = procctl(P_PID, pid, PROC_NO_NEW_PRIVS_STATUS, &arg);
182*acb1f126SEdward Tomasz Napierala 			break;
183bab3f1d0SKonstantin Belousov #ifdef PROC_KPTI_CTL
184bab3f1d0SKonstantin Belousov 		case MODE_KPTI:
185bab3f1d0SKonstantin Belousov 			error = procctl(P_PID, pid, PROC_KPTI_STATUS, &arg);
186bab3f1d0SKonstantin Belousov 			break;
187bab3f1d0SKonstantin Belousov #endif
188da477bcdSKonstantin Belousov #ifdef PROC_LA_CTL
189da477bcdSKonstantin Belousov 		case MODE_LA57:
190da477bcdSKonstantin Belousov 		case MODE_LA48:
191da477bcdSKonstantin Belousov 			error = procctl(P_PID, pid, PROC_LA_STATUS, &arg);
192da477bcdSKonstantin Belousov 			break;
193da477bcdSKonstantin Belousov #endif
1947402f93eSKonstantin Belousov 		default:
1957402f93eSKonstantin Belousov 			usage();
1967402f93eSKonstantin Belousov 			break;
1977402f93eSKonstantin Belousov 		}
1987402f93eSKonstantin Belousov 		if (error != 0)
1997402f93eSKonstantin Belousov 			err(1, "procctl status");
2007402f93eSKonstantin Belousov 		switch (mode) {
201fa50a355SKonstantin Belousov 		case MODE_ASLR:
202fa50a355SKonstantin Belousov 			switch (arg & ~PROC_ASLR_ACTIVE) {
203fa50a355SKonstantin Belousov 			case PROC_ASLR_FORCE_ENABLE:
204fa50a355SKonstantin Belousov 				printf("force enabled");
205fa50a355SKonstantin Belousov 				break;
206fa50a355SKonstantin Belousov 			case PROC_ASLR_FORCE_DISABLE:
207fa50a355SKonstantin Belousov 				printf("force disabled");
208fa50a355SKonstantin Belousov 				break;
209fa50a355SKonstantin Belousov 			case PROC_ASLR_NOFORCE:
210fa50a355SKonstantin Belousov 				printf("not forced");
211fa50a355SKonstantin Belousov 				break;
212fa50a355SKonstantin Belousov 			}
213fa50a355SKonstantin Belousov 			if ((arg & PROC_ASLR_ACTIVE) != 0)
214fa50a355SKonstantin Belousov 				printf(", active\n");
215fa50a355SKonstantin Belousov 			else
216fa50a355SKonstantin Belousov 				printf(", not active\n");
217fa50a355SKonstantin Belousov 			break;
2187402f93eSKonstantin Belousov 		case MODE_TRACE:
2197402f93eSKonstantin Belousov 			if (arg == -1)
2207402f93eSKonstantin Belousov 				printf("disabled\n");
2217402f93eSKonstantin Belousov 			else if (arg == 0)
2227402f93eSKonstantin Belousov 				printf("enabled, no debugger\n");
2237402f93eSKonstantin Belousov 			else
2247402f93eSKonstantin Belousov 				printf("enabled, traced by %d\n", arg);
2257402f93eSKonstantin Belousov 			break;
2267402f93eSKonstantin Belousov 		case MODE_TRAPCAP:
2277402f93eSKonstantin Belousov 			switch (arg) {
2287402f93eSKonstantin Belousov 			case PROC_TRAPCAP_CTL_ENABLE:
2297402f93eSKonstantin Belousov 				printf("enabled\n");
2307402f93eSKonstantin Belousov 				break;
2317402f93eSKonstantin Belousov 			case PROC_TRAPCAP_CTL_DISABLE:
2327402f93eSKonstantin Belousov 				printf("disabled\n");
2337402f93eSKonstantin Belousov 				break;
2347402f93eSKonstantin Belousov 			}
2357402f93eSKonstantin Belousov 			break;
23646922074SKonstantin Belousov 		case MODE_PROTMAX:
23746922074SKonstantin Belousov 			switch (arg & ~PROC_PROTMAX_ACTIVE) {
23846922074SKonstantin Belousov 			case PROC_PROTMAX_FORCE_ENABLE:
23946922074SKonstantin Belousov 				printf("force enabled");
24046922074SKonstantin Belousov 				break;
24146922074SKonstantin Belousov 			case PROC_PROTMAX_FORCE_DISABLE:
24246922074SKonstantin Belousov 				printf("force disabled");
24346922074SKonstantin Belousov 				break;
24446922074SKonstantin Belousov 			case PROC_PROTMAX_NOFORCE:
24546922074SKonstantin Belousov 				printf("not forced");
24646922074SKonstantin Belousov 				break;
24746922074SKonstantin Belousov 			}
24846922074SKonstantin Belousov 			if ((arg & PROC_PROTMAX_ACTIVE) != 0)
24946922074SKonstantin Belousov 				printf(", active\n");
25046922074SKonstantin Belousov 			else
25146922074SKonstantin Belousov 				printf(", not active\n");
25246922074SKonstantin Belousov 			break;
253c22994e3SKonstantin Belousov 		case MODE_STACKGAP:
254c22994e3SKonstantin Belousov 			switch (arg & (PROC_STACKGAP_ENABLE |
255c22994e3SKonstantin Belousov 			    PROC_STACKGAP_DISABLE)) {
256c22994e3SKonstantin Belousov 			case PROC_STACKGAP_ENABLE:
257c22994e3SKonstantin Belousov 				printf("enabled\n");
258c22994e3SKonstantin Belousov 				break;
259c22994e3SKonstantin Belousov 			case PROC_STACKGAP_DISABLE:
260c22994e3SKonstantin Belousov 				printf("disabled\n");
261c22994e3SKonstantin Belousov 				break;
262c22994e3SKonstantin Belousov 			}
263c22994e3SKonstantin Belousov 			switch (arg & (PROC_STACKGAP_ENABLE_EXEC |
264c22994e3SKonstantin Belousov 			    PROC_STACKGAP_DISABLE_EXEC)) {
265c22994e3SKonstantin Belousov 			case PROC_STACKGAP_ENABLE_EXEC:
266c22994e3SKonstantin Belousov 				printf("enabled after exec\n");
267c22994e3SKonstantin Belousov 				break;
268c22994e3SKonstantin Belousov 			case PROC_STACKGAP_DISABLE_EXEC:
269c22994e3SKonstantin Belousov 				printf("disabled after exec\n");
270c22994e3SKonstantin Belousov 				break;
271c22994e3SKonstantin Belousov 			}
272c22994e3SKonstantin Belousov 			break;
273*acb1f126SEdward Tomasz Napierala 		case MODE_NO_NEW_PRIVS:
274*acb1f126SEdward Tomasz Napierala 			switch (arg) {
275*acb1f126SEdward Tomasz Napierala 			case PROC_NO_NEW_PRIVS_ENABLE:
276*acb1f126SEdward Tomasz Napierala 				printf("enabled\n");
277*acb1f126SEdward Tomasz Napierala 				break;
278*acb1f126SEdward Tomasz Napierala 			case PROC_NO_NEW_PRIVS_DISABLE:
279*acb1f126SEdward Tomasz Napierala 				printf("disabled\n");
280*acb1f126SEdward Tomasz Napierala 				break;
281*acb1f126SEdward Tomasz Napierala 			}
282*acb1f126SEdward Tomasz Napierala 			break;
283bab3f1d0SKonstantin Belousov #ifdef PROC_KPTI_CTL
284bab3f1d0SKonstantin Belousov 		case MODE_KPTI:
285bab3f1d0SKonstantin Belousov 			switch (arg & ~PROC_KPTI_STATUS_ACTIVE) {
286bab3f1d0SKonstantin Belousov 			case PROC_KPTI_CTL_ENABLE_ON_EXEC:
287bab3f1d0SKonstantin Belousov 				printf("enabled");
288bab3f1d0SKonstantin Belousov 				break;
289bab3f1d0SKonstantin Belousov 			case PROC_KPTI_CTL_DISABLE_ON_EXEC:
290bab3f1d0SKonstantin Belousov 				printf("disabled");
291bab3f1d0SKonstantin Belousov 				break;
292bab3f1d0SKonstantin Belousov 			}
293bab3f1d0SKonstantin Belousov 			if ((arg & PROC_KPTI_STATUS_ACTIVE) != 0)
294bab3f1d0SKonstantin Belousov 				printf(", active\n");
295bab3f1d0SKonstantin Belousov 			else
296bab3f1d0SKonstantin Belousov 				printf(", not active\n");
297bab3f1d0SKonstantin Belousov 			break;
298bab3f1d0SKonstantin Belousov #endif
299da477bcdSKonstantin Belousov #ifdef PROC_LA_CTL
300da477bcdSKonstantin Belousov 		case MODE_LA57:
301da477bcdSKonstantin Belousov 		case MODE_LA48:
302da477bcdSKonstantin Belousov 			switch (arg & ~(PROC_LA_STATUS_LA48 |
303da477bcdSKonstantin Belousov 			    PROC_LA_STATUS_LA57)) {
304da477bcdSKonstantin Belousov 			case PROC_LA_CTL_LA48_ON_EXEC:
305da477bcdSKonstantin Belousov 				printf("la48 on exec");
306da477bcdSKonstantin Belousov 				break;
307da477bcdSKonstantin Belousov 			case PROC_LA_CTL_LA57_ON_EXEC:
308da477bcdSKonstantin Belousov 				printf("la57 on exec");
309da477bcdSKonstantin Belousov 				break;
310da477bcdSKonstantin Belousov 			case PROC_LA_CTL_DEFAULT_ON_EXEC:
311da477bcdSKonstantin Belousov 				printf("default on exec");
312da477bcdSKonstantin Belousov 				break;
313da477bcdSKonstantin Belousov 			}
314da477bcdSKonstantin Belousov 			if ((arg & PROC_LA_STATUS_LA48) != 0)
315da477bcdSKonstantin Belousov 				printf(", la48 active\n");
316da477bcdSKonstantin Belousov 			else if ((arg & PROC_LA_STATUS_LA57) != 0)
317da477bcdSKonstantin Belousov 				printf(", la57 active\n");
318da477bcdSKonstantin Belousov 			break;
319da477bcdSKonstantin Belousov #endif
3207402f93eSKonstantin Belousov 		}
3217402f93eSKonstantin Belousov 	} else {
3227402f93eSKonstantin Belousov 		switch (mode) {
323fa50a355SKonstantin Belousov 		case MODE_ASLR:
324fa50a355SKonstantin Belousov 			arg = enable ? PROC_ASLR_FORCE_ENABLE :
325fa50a355SKonstantin Belousov 			    PROC_ASLR_FORCE_DISABLE;
326fa50a355SKonstantin Belousov 			error = procctl(P_PID, pid, PROC_ASLR_CTL, &arg);
327fa50a355SKonstantin Belousov 			break;
3287402f93eSKonstantin Belousov 		case MODE_TRACE:
3297402f93eSKonstantin Belousov 			arg = enable ? PROC_TRACE_CTL_ENABLE :
3307402f93eSKonstantin Belousov 			    PROC_TRACE_CTL_DISABLE;
3317402f93eSKonstantin Belousov 			error = procctl(P_PID, pid, PROC_TRACE_CTL, &arg);
3327402f93eSKonstantin Belousov 			break;
3337402f93eSKonstantin Belousov 		case MODE_TRAPCAP:
3347402f93eSKonstantin Belousov 			arg = enable ? PROC_TRAPCAP_CTL_ENABLE :
3357402f93eSKonstantin Belousov 			    PROC_TRAPCAP_CTL_DISABLE;
3367402f93eSKonstantin Belousov 			error = procctl(P_PID, pid, PROC_TRAPCAP_CTL, &arg);
3377402f93eSKonstantin Belousov 			break;
33846922074SKonstantin Belousov 		case MODE_PROTMAX:
33946922074SKonstantin Belousov 			arg = enable ? PROC_PROTMAX_FORCE_ENABLE :
34046922074SKonstantin Belousov 			    PROC_PROTMAX_FORCE_DISABLE;
34146922074SKonstantin Belousov 			error = procctl(P_PID, pid, PROC_PROTMAX_CTL, &arg);
34246922074SKonstantin Belousov 			break;
343c22994e3SKonstantin Belousov 		case MODE_STACKGAP:
344c22994e3SKonstantin Belousov 			arg = enable ? PROC_STACKGAP_ENABLE_EXEC :
345c22994e3SKonstantin Belousov 			    (PROC_STACKGAP_DISABLE |
346c22994e3SKonstantin Belousov 			    PROC_STACKGAP_DISABLE_EXEC);
347c22994e3SKonstantin Belousov 			error = procctl(P_PID, pid, PROC_STACKGAP_CTL, &arg);
348c22994e3SKonstantin Belousov 			break;
349*acb1f126SEdward Tomasz Napierala 		case MODE_NO_NEW_PRIVS:
350*acb1f126SEdward Tomasz Napierala 			arg = enable ? PROC_NO_NEW_PRIVS_ENABLE :
351*acb1f126SEdward Tomasz Napierala 			    PROC_NO_NEW_PRIVS_DISABLE;
352*acb1f126SEdward Tomasz Napierala 			error = procctl(P_PID, pid, PROC_NO_NEW_PRIVS_CTL, &arg);
353*acb1f126SEdward Tomasz Napierala 			break;
354bab3f1d0SKonstantin Belousov #ifdef PROC_KPTI_CTL
355bab3f1d0SKonstantin Belousov 		case MODE_KPTI:
356bab3f1d0SKonstantin Belousov 			arg = enable ? PROC_KPTI_CTL_ENABLE_ON_EXEC :
357bab3f1d0SKonstantin Belousov 			    PROC_KPTI_CTL_DISABLE_ON_EXEC;
358bab3f1d0SKonstantin Belousov 			error = procctl(P_PID, pid, PROC_KPTI_CTL, &arg);
359bab3f1d0SKonstantin Belousov 			break;
360bab3f1d0SKonstantin Belousov #endif
361da477bcdSKonstantin Belousov #ifdef PROC_LA_CTL
362da477bcdSKonstantin Belousov 		case MODE_LA57:
363da477bcdSKonstantin Belousov 			arg = enable ? PROC_LA_CTL_LA57_ON_EXEC :
364da477bcdSKonstantin Belousov 			    PROC_LA_CTL_DEFAULT_ON_EXEC;
365da477bcdSKonstantin Belousov 			error = procctl(P_PID, pid, PROC_LA_CTL, &arg);
366da477bcdSKonstantin Belousov 			break;
367da477bcdSKonstantin Belousov 		case MODE_LA48:
368da477bcdSKonstantin Belousov 			arg = enable ? PROC_LA_CTL_LA48_ON_EXEC :
369da477bcdSKonstantin Belousov 			    PROC_LA_CTL_DEFAULT_ON_EXEC;
370da477bcdSKonstantin Belousov 			error = procctl(P_PID, pid, PROC_LA_CTL, &arg);
371da477bcdSKonstantin Belousov 			break;
372da477bcdSKonstantin Belousov #endif
3737402f93eSKonstantin Belousov 		default:
3747402f93eSKonstantin Belousov 			usage();
3757402f93eSKonstantin Belousov 			break;
3767402f93eSKonstantin Belousov 		}
3777402f93eSKonstantin Belousov 		if (error != 0)
3787402f93eSKonstantin Belousov 			err(1, "procctl ctl");
3797402f93eSKonstantin Belousov 		if (do_command) {
3807402f93eSKonstantin Belousov 			error = execvp(argv[0], argv);
3817402f93eSKonstantin Belousov 			err(1, "exec");
3827402f93eSKonstantin Belousov 		}
3837402f93eSKonstantin Belousov 	}
3847402f93eSKonstantin Belousov 	exit(0);
3857402f93eSKonstantin Belousov }
386