xref: /freebsd/usr.bin/proccontrol/proccontrol.c (revision 7ca260df8cea7dea41e7a16362a3c5c45e86249c)
17402f93eSKonstantin Belousov /*-
27402f93eSKonstantin Belousov  * Copyright (c) 2016 The FreeBSD Foundation
37402f93eSKonstantin Belousov  *
47402f93eSKonstantin Belousov  * This software was developed by Konstantin Belousov <kib@FreeBSD.org>
57402f93eSKonstantin Belousov  * under sponsorship from the FreeBSD Foundation.
67402f93eSKonstantin Belousov  *
77402f93eSKonstantin Belousov  * Redistribution and use in source and binary forms, with or without
87402f93eSKonstantin Belousov  * modification, are permitted provided that the following conditions
97402f93eSKonstantin Belousov  * are met:
107402f93eSKonstantin Belousov  * 1. Redistributions of source code must retain the above copyright
117402f93eSKonstantin Belousov  *    notice, this list of conditions and the following disclaimer.
127402f93eSKonstantin Belousov  * 2. Redistributions in binary form must reproduce the above copyright
137402f93eSKonstantin Belousov  *    notice, this list of conditions and the following disclaimer in the
147402f93eSKonstantin Belousov  *    documentation and/or other materials provided with the distribution.
157402f93eSKonstantin Belousov  *
167402f93eSKonstantin Belousov  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
177402f93eSKonstantin Belousov  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
187402f93eSKonstantin Belousov  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
197402f93eSKonstantin Belousov  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
207402f93eSKonstantin Belousov  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
217402f93eSKonstantin Belousov  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
227402f93eSKonstantin Belousov  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
237402f93eSKonstantin Belousov  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
247402f93eSKonstantin Belousov  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
257402f93eSKonstantin Belousov  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
267402f93eSKonstantin Belousov  * SUCH DAMAGE.
277402f93eSKonstantin Belousov  */
287402f93eSKonstantin Belousov 
29*7ca260dfSBrooks Davis #include <sys/param.h>
307402f93eSKonstantin Belousov #include <sys/procctl.h>
317402f93eSKonstantin Belousov #include <err.h>
327402f93eSKonstantin Belousov #include <stdbool.h>
337402f93eSKonstantin Belousov #include <stdio.h>
347402f93eSKonstantin Belousov #include <stdlib.h>
357402f93eSKonstantin Belousov #include <string.h>
367402f93eSKonstantin Belousov #include <unistd.h>
377402f93eSKonstantin Belousov 
38*7ca260dfSBrooks Davis enum mode {
397402f93eSKonstantin Belousov 	MODE_INVALID,
40*7ca260dfSBrooks Davis 	MODE_ASLR,
417402f93eSKonstantin Belousov 	MODE_TRACE,
427402f93eSKonstantin Belousov 	MODE_TRAPCAP,
4346922074SKonstantin Belousov 	MODE_PROTMAX,
44c22994e3SKonstantin Belousov 	MODE_STACKGAP,
45acb1f126SEdward Tomasz Napierala 	MODE_NO_NEW_PRIVS,
46ac8af193SKonstantin Belousov 	MODE_WXMAP,
47bab3f1d0SKonstantin Belousov #ifdef PROC_KPTI_CTL
48bab3f1d0SKonstantin Belousov 	MODE_KPTI,
49bab3f1d0SKonstantin Belousov #endif
50da477bcdSKonstantin Belousov #ifdef PROC_LA_CTL
51da477bcdSKonstantin Belousov 	MODE_LA57,
52da477bcdSKonstantin Belousov 	MODE_LA48,
53da477bcdSKonstantin Belousov #endif
547402f93eSKonstantin Belousov };
557402f93eSKonstantin Belousov 
56*7ca260dfSBrooks Davis static const struct {
57*7ca260dfSBrooks Davis 	enum mode mode;
58*7ca260dfSBrooks Davis 	const char *name;
59*7ca260dfSBrooks Davis } modes[] = {
60*7ca260dfSBrooks Davis 	{ MODE_ASLR,		"aslr" },
61*7ca260dfSBrooks Davis 	{ MODE_TRACE,		"trace" },
62*7ca260dfSBrooks Davis 	{ MODE_TRAPCAP,		"trapcap" },
63*7ca260dfSBrooks Davis 	{ MODE_PROTMAX,		"protmax" },
64*7ca260dfSBrooks Davis 	{ MODE_STACKGAP, 	"stackgap" },
65*7ca260dfSBrooks Davis 	{ MODE_NO_NEW_PRIVS,	"nonewprivs" },
66*7ca260dfSBrooks Davis 	{ MODE_WXMAP,		"wxmap" },
67*7ca260dfSBrooks Davis #ifdef PROC_KPTI_CTL
68*7ca260dfSBrooks Davis 	{ MODE_KPTI, 		"kpti" },
69*7ca260dfSBrooks Davis #endif
70*7ca260dfSBrooks Davis #ifdef PROC_LA_CTL
71*7ca260dfSBrooks Davis 	{ MODE_LA57,		"la57" },
72*7ca260dfSBrooks Davis 	{ MODE_LA48,		"la48" },
73*7ca260dfSBrooks Davis #endif
74*7ca260dfSBrooks Davis };
75*7ca260dfSBrooks Davis 
767402f93eSKonstantin Belousov static pid_t
str2pid(const char * str)777402f93eSKonstantin Belousov str2pid(const char *str)
787402f93eSKonstantin Belousov {
797402f93eSKonstantin Belousov 	pid_t res;
807402f93eSKonstantin Belousov 	char *tail;
817402f93eSKonstantin Belousov 
827402f93eSKonstantin Belousov 	res = strtol(str, &tail, 0);
837402f93eSKonstantin Belousov 	if (*tail != '\0') {
847402f93eSKonstantin Belousov 		warnx("non-numeric pid");
857402f93eSKonstantin Belousov 		return (-1);
867402f93eSKonstantin Belousov 	}
877402f93eSKonstantin Belousov 	return (res);
887402f93eSKonstantin Belousov }
897402f93eSKonstantin Belousov 
907402f93eSKonstantin Belousov static void __dead2
usage(void)917402f93eSKonstantin Belousov usage(void)
927402f93eSKonstantin Belousov {
9370174ef7SBrooks Davis 	fprintf(stderr, "Usage:\n");
9470174ef7SBrooks Davis 	fprintf(stderr, "    proccontrol -m mode -s (enable|disable) "
9570174ef7SBrooks Davis 	    "(-p pid | command)\n");
9670174ef7SBrooks Davis 	fprintf(stderr, "    proccontrol -m mode -q [-p pid]\n");
97*7ca260dfSBrooks Davis 	fprintf(stderr, "Modes: ");
98*7ca260dfSBrooks Davis 	for (size_t i = 0; i < nitems(modes); i++)
99*7ca260dfSBrooks Davis 		fprintf(stderr, "%s%s", i == 0 ? "" : "|", modes[i].name);
100*7ca260dfSBrooks Davis 	fprintf(stderr, "\n");
1017402f93eSKonstantin Belousov 	exit(1);
1027402f93eSKonstantin Belousov }
1037402f93eSKonstantin Belousov 
1047402f93eSKonstantin Belousov int
main(int argc,char * argv[])1057402f93eSKonstantin Belousov main(int argc, char *argv[])
1067402f93eSKonstantin Belousov {
1077402f93eSKonstantin Belousov 	int arg, ch, error, mode;
1087402f93eSKonstantin Belousov 	pid_t pid;
1097402f93eSKonstantin Belousov 	bool enable, do_command, query;
1107402f93eSKonstantin Belousov 
1117402f93eSKonstantin Belousov 	mode = MODE_INVALID;
1127402f93eSKonstantin Belousov 	enable = true;
1137402f93eSKonstantin Belousov 	pid = -1;
1147402f93eSKonstantin Belousov 	query = false;
1157402f93eSKonstantin Belousov 	while ((ch = getopt(argc, argv, "m:qs:p:")) != -1) {
1167402f93eSKonstantin Belousov 		switch (ch) {
1177402f93eSKonstantin Belousov 		case 'm':
118*7ca260dfSBrooks Davis 			if (mode != MODE_INVALID)
119*7ca260dfSBrooks Davis 				usage();
120*7ca260dfSBrooks Davis 			for (size_t i = 0; i < nitems(modes); i++) {
121*7ca260dfSBrooks Davis 				if (strcmp(optarg, modes[i].name) == 0) {
122*7ca260dfSBrooks Davis 					mode = modes[i].mode;
123*7ca260dfSBrooks Davis 					break;
124*7ca260dfSBrooks Davis 				}
125*7ca260dfSBrooks Davis 			}
126*7ca260dfSBrooks Davis 			if (mode == MODE_INVALID)
1277402f93eSKonstantin Belousov 				usage();
1287402f93eSKonstantin Belousov 			break;
1297402f93eSKonstantin Belousov 		case 's':
1307402f93eSKonstantin Belousov 			if (strcmp(optarg, "enable") == 0)
1317402f93eSKonstantin Belousov 				enable = true;
1327402f93eSKonstantin Belousov 			else if (strcmp(optarg, "disable") == 0)
1337402f93eSKonstantin Belousov 				enable = false;
1347402f93eSKonstantin Belousov 			else
1357402f93eSKonstantin Belousov 				usage();
1367402f93eSKonstantin Belousov 			break;
1377402f93eSKonstantin Belousov 		case 'p':
1387402f93eSKonstantin Belousov 			pid = str2pid(optarg);
1397402f93eSKonstantin Belousov 			break;
1407402f93eSKonstantin Belousov 		case 'q':
1417402f93eSKonstantin Belousov 			query = true;
1427402f93eSKonstantin Belousov 			break;
1437402f93eSKonstantin Belousov 		case '?':
1447402f93eSKonstantin Belousov 		default:
1457402f93eSKonstantin Belousov 			usage();
1467402f93eSKonstantin Belousov 			break;
1477402f93eSKonstantin Belousov 		}
1487402f93eSKonstantin Belousov 	}
1497402f93eSKonstantin Belousov 	argc -= optind;
1507402f93eSKonstantin Belousov 	argv += optind;
1517402f93eSKonstantin Belousov 	do_command = argc != 0;
1527402f93eSKonstantin Belousov 	if (do_command) {
1537402f93eSKonstantin Belousov 		if (pid != -1 || query)
1547402f93eSKonstantin Belousov 			usage();
1557402f93eSKonstantin Belousov 		pid = getpid();
1567402f93eSKonstantin Belousov 	} else if (pid == -1) {
15770174ef7SBrooks Davis 		if (!query)
15870174ef7SBrooks Davis 			usage();
1597402f93eSKonstantin Belousov 		pid = getpid();
1607402f93eSKonstantin Belousov 	}
1617402f93eSKonstantin Belousov 
1627402f93eSKonstantin Belousov 	if (query) {
1637402f93eSKonstantin Belousov 		switch (mode) {
164fa50a355SKonstantin Belousov 		case MODE_ASLR:
165fa50a355SKonstantin Belousov 			error = procctl(P_PID, pid, PROC_ASLR_STATUS, &arg);
166fa50a355SKonstantin Belousov 			break;
1677402f93eSKonstantin Belousov 		case MODE_TRACE:
1687402f93eSKonstantin Belousov 			error = procctl(P_PID, pid, PROC_TRACE_STATUS, &arg);
1697402f93eSKonstantin Belousov 			break;
1707402f93eSKonstantin Belousov 		case MODE_TRAPCAP:
1717402f93eSKonstantin Belousov 			error = procctl(P_PID, pid, PROC_TRAPCAP_STATUS, &arg);
1727402f93eSKonstantin Belousov 			break;
17346922074SKonstantin Belousov 		case MODE_PROTMAX:
17446922074SKonstantin Belousov 			error = procctl(P_PID, pid, PROC_PROTMAX_STATUS, &arg);
17546922074SKonstantin Belousov 			break;
176c22994e3SKonstantin Belousov 		case MODE_STACKGAP:
177c22994e3SKonstantin Belousov 			error = procctl(P_PID, pid, PROC_STACKGAP_STATUS, &arg);
178c22994e3SKonstantin Belousov 			break;
179acb1f126SEdward Tomasz Napierala 		case MODE_NO_NEW_PRIVS:
1801349891aSKonstantin Belousov 			error = procctl(P_PID, pid, PROC_NO_NEW_PRIVS_STATUS,
1811349891aSKonstantin Belousov 			    &arg);
182acb1f126SEdward Tomasz Napierala 			break;
183ac8af193SKonstantin Belousov 		case MODE_WXMAP:
184ac8af193SKonstantin Belousov 			error = procctl(P_PID, pid, PROC_WXMAP_STATUS, &arg);
185ac8af193SKonstantin Belousov 			break;
186bab3f1d0SKonstantin Belousov #ifdef PROC_KPTI_CTL
187bab3f1d0SKonstantin Belousov 		case MODE_KPTI:
188bab3f1d0SKonstantin Belousov 			error = procctl(P_PID, pid, PROC_KPTI_STATUS, &arg);
189bab3f1d0SKonstantin Belousov 			break;
190bab3f1d0SKonstantin Belousov #endif
191da477bcdSKonstantin Belousov #ifdef PROC_LA_CTL
192da477bcdSKonstantin Belousov 		case MODE_LA57:
193da477bcdSKonstantin Belousov 		case MODE_LA48:
194da477bcdSKonstantin Belousov 			error = procctl(P_PID, pid, PROC_LA_STATUS, &arg);
195da477bcdSKonstantin Belousov 			break;
196da477bcdSKonstantin Belousov #endif
1977402f93eSKonstantin Belousov 		default:
1987402f93eSKonstantin Belousov 			usage();
1997402f93eSKonstantin Belousov 			break;
2007402f93eSKonstantin Belousov 		}
2017402f93eSKonstantin Belousov 		if (error != 0)
2027402f93eSKonstantin Belousov 			err(1, "procctl status");
2037402f93eSKonstantin Belousov 		switch (mode) {
204fa50a355SKonstantin Belousov 		case MODE_ASLR:
205fa50a355SKonstantin Belousov 			switch (arg & ~PROC_ASLR_ACTIVE) {
206fa50a355SKonstantin Belousov 			case PROC_ASLR_FORCE_ENABLE:
207fa50a355SKonstantin Belousov 				printf("force enabled");
208fa50a355SKonstantin Belousov 				break;
209fa50a355SKonstantin Belousov 			case PROC_ASLR_FORCE_DISABLE:
210fa50a355SKonstantin Belousov 				printf("force disabled");
211fa50a355SKonstantin Belousov 				break;
212fa50a355SKonstantin Belousov 			case PROC_ASLR_NOFORCE:
213fa50a355SKonstantin Belousov 				printf("not forced");
214fa50a355SKonstantin Belousov 				break;
215fa50a355SKonstantin Belousov 			}
216fa50a355SKonstantin Belousov 			if ((arg & PROC_ASLR_ACTIVE) != 0)
217fa50a355SKonstantin Belousov 				printf(", active\n");
218fa50a355SKonstantin Belousov 			else
219fa50a355SKonstantin Belousov 				printf(", not active\n");
220fa50a355SKonstantin Belousov 			break;
2217402f93eSKonstantin Belousov 		case MODE_TRACE:
2227402f93eSKonstantin Belousov 			if (arg == -1)
2237402f93eSKonstantin Belousov 				printf("disabled\n");
2247402f93eSKonstantin Belousov 			else if (arg == 0)
2257402f93eSKonstantin Belousov 				printf("enabled, no debugger\n");
2267402f93eSKonstantin Belousov 			else
2277402f93eSKonstantin Belousov 				printf("enabled, traced by %d\n", arg);
2287402f93eSKonstantin Belousov 			break;
2297402f93eSKonstantin Belousov 		case MODE_TRAPCAP:
2307402f93eSKonstantin Belousov 			switch (arg) {
2317402f93eSKonstantin Belousov 			case PROC_TRAPCAP_CTL_ENABLE:
2327402f93eSKonstantin Belousov 				printf("enabled\n");
2337402f93eSKonstantin Belousov 				break;
2347402f93eSKonstantin Belousov 			case PROC_TRAPCAP_CTL_DISABLE:
2357402f93eSKonstantin Belousov 				printf("disabled\n");
2367402f93eSKonstantin Belousov 				break;
2377402f93eSKonstantin Belousov 			}
2387402f93eSKonstantin Belousov 			break;
23946922074SKonstantin Belousov 		case MODE_PROTMAX:
24046922074SKonstantin Belousov 			switch (arg & ~PROC_PROTMAX_ACTIVE) {
24146922074SKonstantin Belousov 			case PROC_PROTMAX_FORCE_ENABLE:
24246922074SKonstantin Belousov 				printf("force enabled");
24346922074SKonstantin Belousov 				break;
24446922074SKonstantin Belousov 			case PROC_PROTMAX_FORCE_DISABLE:
24546922074SKonstantin Belousov 				printf("force disabled");
24646922074SKonstantin Belousov 				break;
24746922074SKonstantin Belousov 			case PROC_PROTMAX_NOFORCE:
24846922074SKonstantin Belousov 				printf("not forced");
24946922074SKonstantin Belousov 				break;
25046922074SKonstantin Belousov 			}
25146922074SKonstantin Belousov 			if ((arg & PROC_PROTMAX_ACTIVE) != 0)
25246922074SKonstantin Belousov 				printf(", active\n");
25346922074SKonstantin Belousov 			else
25446922074SKonstantin Belousov 				printf(", not active\n");
25546922074SKonstantin Belousov 			break;
256c22994e3SKonstantin Belousov 		case MODE_STACKGAP:
257c22994e3SKonstantin Belousov 			switch (arg & (PROC_STACKGAP_ENABLE |
258c22994e3SKonstantin Belousov 			    PROC_STACKGAP_DISABLE)) {
259c22994e3SKonstantin Belousov 			case PROC_STACKGAP_ENABLE:
260c22994e3SKonstantin Belousov 				printf("enabled\n");
261c22994e3SKonstantin Belousov 				break;
262c22994e3SKonstantin Belousov 			case PROC_STACKGAP_DISABLE:
263c22994e3SKonstantin Belousov 				printf("disabled\n");
264c22994e3SKonstantin Belousov 				break;
265c22994e3SKonstantin Belousov 			}
266c22994e3SKonstantin Belousov 			switch (arg & (PROC_STACKGAP_ENABLE_EXEC |
267c22994e3SKonstantin Belousov 			    PROC_STACKGAP_DISABLE_EXEC)) {
268c22994e3SKonstantin Belousov 			case PROC_STACKGAP_ENABLE_EXEC:
269c22994e3SKonstantin Belousov 				printf("enabled after exec\n");
270c22994e3SKonstantin Belousov 				break;
271c22994e3SKonstantin Belousov 			case PROC_STACKGAP_DISABLE_EXEC:
272c22994e3SKonstantin Belousov 				printf("disabled after exec\n");
273c22994e3SKonstantin Belousov 				break;
274c22994e3SKonstantin Belousov 			}
275c22994e3SKonstantin Belousov 			break;
276acb1f126SEdward Tomasz Napierala 		case MODE_NO_NEW_PRIVS:
277acb1f126SEdward Tomasz Napierala 			switch (arg) {
278acb1f126SEdward Tomasz Napierala 			case PROC_NO_NEW_PRIVS_ENABLE:
279acb1f126SEdward Tomasz Napierala 				printf("enabled\n");
280acb1f126SEdward Tomasz Napierala 				break;
281acb1f126SEdward Tomasz Napierala 			case PROC_NO_NEW_PRIVS_DISABLE:
282acb1f126SEdward Tomasz Napierala 				printf("disabled\n");
283acb1f126SEdward Tomasz Napierala 				break;
284acb1f126SEdward Tomasz Napierala 			}
285acb1f126SEdward Tomasz Napierala 			break;
286ac8af193SKonstantin Belousov 		case MODE_WXMAP:
287ac8af193SKonstantin Belousov 			if ((arg & PROC_WX_MAPPINGS_PERMIT) != 0)
288ac8af193SKonstantin Belousov 				printf("enabled");
289ac8af193SKonstantin Belousov 			else
290ac8af193SKonstantin Belousov 				printf("disabled");
291ac8af193SKonstantin Belousov 			if ((arg & PROC_WX_MAPPINGS_DISALLOW_EXEC) != 0)
292ac8af193SKonstantin Belousov 				printf(", disabled on exec");
293ac8af193SKonstantin Belousov 			if ((arg & PROC_WXORX_ENFORCE) != 0)
294ac8af193SKonstantin Belousov 				printf(", wxorx enforced");
295ac8af193SKonstantin Belousov 			printf("\n");
296ac8af193SKonstantin Belousov 			break;
297bab3f1d0SKonstantin Belousov #ifdef PROC_KPTI_CTL
298bab3f1d0SKonstantin Belousov 		case MODE_KPTI:
299bab3f1d0SKonstantin Belousov 			switch (arg & ~PROC_KPTI_STATUS_ACTIVE) {
300bab3f1d0SKonstantin Belousov 			case PROC_KPTI_CTL_ENABLE_ON_EXEC:
301bab3f1d0SKonstantin Belousov 				printf("enabled");
302bab3f1d0SKonstantin Belousov 				break;
303bab3f1d0SKonstantin Belousov 			case PROC_KPTI_CTL_DISABLE_ON_EXEC:
304bab3f1d0SKonstantin Belousov 				printf("disabled");
305bab3f1d0SKonstantin Belousov 				break;
306bab3f1d0SKonstantin Belousov 			}
307bab3f1d0SKonstantin Belousov 			if ((arg & PROC_KPTI_STATUS_ACTIVE) != 0)
308bab3f1d0SKonstantin Belousov 				printf(", active\n");
309bab3f1d0SKonstantin Belousov 			else
310bab3f1d0SKonstantin Belousov 				printf(", not active\n");
311bab3f1d0SKonstantin Belousov 			break;
312bab3f1d0SKonstantin Belousov #endif
313da477bcdSKonstantin Belousov #ifdef PROC_LA_CTL
314da477bcdSKonstantin Belousov 		case MODE_LA57:
315da477bcdSKonstantin Belousov 		case MODE_LA48:
316da477bcdSKonstantin Belousov 			switch (arg & ~(PROC_LA_STATUS_LA48 |
317da477bcdSKonstantin Belousov 			    PROC_LA_STATUS_LA57)) {
318da477bcdSKonstantin Belousov 			case PROC_LA_CTL_LA48_ON_EXEC:
319da477bcdSKonstantin Belousov 				printf("la48 on exec");
320da477bcdSKonstantin Belousov 				break;
321da477bcdSKonstantin Belousov 			case PROC_LA_CTL_LA57_ON_EXEC:
322da477bcdSKonstantin Belousov 				printf("la57 on exec");
323da477bcdSKonstantin Belousov 				break;
324da477bcdSKonstantin Belousov 			case PROC_LA_CTL_DEFAULT_ON_EXEC:
325da477bcdSKonstantin Belousov 				printf("default on exec");
326da477bcdSKonstantin Belousov 				break;
327da477bcdSKonstantin Belousov 			}
328da477bcdSKonstantin Belousov 			if ((arg & PROC_LA_STATUS_LA48) != 0)
329da477bcdSKonstantin Belousov 				printf(", la48 active\n");
330da477bcdSKonstantin Belousov 			else if ((arg & PROC_LA_STATUS_LA57) != 0)
331da477bcdSKonstantin Belousov 				printf(", la57 active\n");
332da477bcdSKonstantin Belousov 			break;
333da477bcdSKonstantin Belousov #endif
3347402f93eSKonstantin Belousov 		}
3357402f93eSKonstantin Belousov 	} else {
3367402f93eSKonstantin Belousov 		switch (mode) {
337fa50a355SKonstantin Belousov 		case MODE_ASLR:
338fa50a355SKonstantin Belousov 			arg = enable ? PROC_ASLR_FORCE_ENABLE :
339fa50a355SKonstantin Belousov 			    PROC_ASLR_FORCE_DISABLE;
340fa50a355SKonstantin Belousov 			error = procctl(P_PID, pid, PROC_ASLR_CTL, &arg);
341fa50a355SKonstantin Belousov 			break;
3427402f93eSKonstantin Belousov 		case MODE_TRACE:
3437402f93eSKonstantin Belousov 			arg = enable ? PROC_TRACE_CTL_ENABLE :
3447402f93eSKonstantin Belousov 			    PROC_TRACE_CTL_DISABLE;
3457402f93eSKonstantin Belousov 			error = procctl(P_PID, pid, PROC_TRACE_CTL, &arg);
3467402f93eSKonstantin Belousov 			break;
3477402f93eSKonstantin Belousov 		case MODE_TRAPCAP:
3487402f93eSKonstantin Belousov 			arg = enable ? PROC_TRAPCAP_CTL_ENABLE :
3497402f93eSKonstantin Belousov 			    PROC_TRAPCAP_CTL_DISABLE;
3507402f93eSKonstantin Belousov 			error = procctl(P_PID, pid, PROC_TRAPCAP_CTL, &arg);
3517402f93eSKonstantin Belousov 			break;
35246922074SKonstantin Belousov 		case MODE_PROTMAX:
35346922074SKonstantin Belousov 			arg = enable ? PROC_PROTMAX_FORCE_ENABLE :
35446922074SKonstantin Belousov 			    PROC_PROTMAX_FORCE_DISABLE;
35546922074SKonstantin Belousov 			error = procctl(P_PID, pid, PROC_PROTMAX_CTL, &arg);
35646922074SKonstantin Belousov 			break;
357c22994e3SKonstantin Belousov 		case MODE_STACKGAP:
358c22994e3SKonstantin Belousov 			arg = enable ? PROC_STACKGAP_ENABLE_EXEC :
359c22994e3SKonstantin Belousov 			    (PROC_STACKGAP_DISABLE |
360c22994e3SKonstantin Belousov 			    PROC_STACKGAP_DISABLE_EXEC);
361c22994e3SKonstantin Belousov 			error = procctl(P_PID, pid, PROC_STACKGAP_CTL, &arg);
362c22994e3SKonstantin Belousov 			break;
363acb1f126SEdward Tomasz Napierala 		case MODE_NO_NEW_PRIVS:
364acb1f126SEdward Tomasz Napierala 			arg = enable ? PROC_NO_NEW_PRIVS_ENABLE :
365acb1f126SEdward Tomasz Napierala 			    PROC_NO_NEW_PRIVS_DISABLE;
3661349891aSKonstantin Belousov 			error = procctl(P_PID, pid, PROC_NO_NEW_PRIVS_CTL,
3671349891aSKonstantin Belousov 			    &arg);
368acb1f126SEdward Tomasz Napierala 			break;
369ac8af193SKonstantin Belousov 		case MODE_WXMAP:
370ac8af193SKonstantin Belousov 			arg = enable ? PROC_WX_MAPPINGS_PERMIT :
371ac8af193SKonstantin Belousov 			    PROC_WX_MAPPINGS_DISALLOW_EXEC;
372ac8af193SKonstantin Belousov 			error = procctl(P_PID, pid, PROC_WXMAP_CTL, &arg);
373ac8af193SKonstantin Belousov 			break;
374bab3f1d0SKonstantin Belousov #ifdef PROC_KPTI_CTL
375bab3f1d0SKonstantin Belousov 		case MODE_KPTI:
376bab3f1d0SKonstantin Belousov 			arg = enable ? PROC_KPTI_CTL_ENABLE_ON_EXEC :
377bab3f1d0SKonstantin Belousov 			    PROC_KPTI_CTL_DISABLE_ON_EXEC;
378bab3f1d0SKonstantin Belousov 			error = procctl(P_PID, pid, PROC_KPTI_CTL, &arg);
379bab3f1d0SKonstantin Belousov 			break;
380bab3f1d0SKonstantin Belousov #endif
381da477bcdSKonstantin Belousov #ifdef PROC_LA_CTL
382da477bcdSKonstantin Belousov 		case MODE_LA57:
383da477bcdSKonstantin Belousov 			arg = enable ? PROC_LA_CTL_LA57_ON_EXEC :
384da477bcdSKonstantin Belousov 			    PROC_LA_CTL_DEFAULT_ON_EXEC;
385da477bcdSKonstantin Belousov 			error = procctl(P_PID, pid, PROC_LA_CTL, &arg);
386da477bcdSKonstantin Belousov 			break;
387da477bcdSKonstantin Belousov 		case MODE_LA48:
388da477bcdSKonstantin Belousov 			arg = enable ? PROC_LA_CTL_LA48_ON_EXEC :
389da477bcdSKonstantin Belousov 			    PROC_LA_CTL_DEFAULT_ON_EXEC;
390da477bcdSKonstantin Belousov 			error = procctl(P_PID, pid, PROC_LA_CTL, &arg);
391da477bcdSKonstantin Belousov 			break;
392da477bcdSKonstantin Belousov #endif
3937402f93eSKonstantin Belousov 		default:
3947402f93eSKonstantin Belousov 			usage();
3957402f93eSKonstantin Belousov 			break;
3967402f93eSKonstantin Belousov 		}
3977402f93eSKonstantin Belousov 		if (error != 0)
3987402f93eSKonstantin Belousov 			err(1, "procctl ctl");
3997402f93eSKonstantin Belousov 		if (do_command) {
4007402f93eSKonstantin Belousov 			error = execvp(argv[0], argv);
4017402f93eSKonstantin Belousov 			err(1, "exec");
4027402f93eSKonstantin Belousov 		}
4037402f93eSKonstantin Belousov 	}
4047402f93eSKonstantin Belousov 	exit(0);
4057402f93eSKonstantin Belousov }
406