xref: /freebsd/usr.bin/proccontrol/proccontrol.c (revision 1d386b48)
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 #include <sys/procctl.h>
327402f93eSKonstantin Belousov #include <err.h>
337402f93eSKonstantin Belousov #include <stdbool.h>
347402f93eSKonstantin Belousov #include <stdio.h>
357402f93eSKonstantin Belousov #include <stdlib.h>
367402f93eSKonstantin Belousov #include <string.h>
377402f93eSKonstantin Belousov #include <unistd.h>
387402f93eSKonstantin Belousov 
397402f93eSKonstantin Belousov enum {
40fa50a355SKonstantin Belousov 	MODE_ASLR,
417402f93eSKonstantin Belousov 	MODE_INVALID,
427402f93eSKonstantin Belousov 	MODE_TRACE,
437402f93eSKonstantin Belousov 	MODE_TRAPCAP,
4446922074SKonstantin Belousov 	MODE_PROTMAX,
45c22994e3SKonstantin Belousov 	MODE_STACKGAP,
46acb1f126SEdward Tomasz Napierala 	MODE_NO_NEW_PRIVS,
47ac8af193SKonstantin Belousov 	MODE_WXMAP,
48bab3f1d0SKonstantin Belousov #ifdef PROC_KPTI_CTL
49bab3f1d0SKonstantin Belousov 	MODE_KPTI,
50bab3f1d0SKonstantin Belousov #endif
51da477bcdSKonstantin Belousov #ifdef PROC_LA_CTL
52da477bcdSKonstantin Belousov 	MODE_LA57,
53da477bcdSKonstantin Belousov 	MODE_LA48,
54da477bcdSKonstantin Belousov #endif
557402f93eSKonstantin Belousov };
567402f93eSKonstantin Belousov 
577402f93eSKonstantin Belousov static pid_t
str2pid(const char * str)587402f93eSKonstantin Belousov str2pid(const char *str)
597402f93eSKonstantin Belousov {
607402f93eSKonstantin Belousov 	pid_t res;
617402f93eSKonstantin Belousov 	char *tail;
627402f93eSKonstantin Belousov 
637402f93eSKonstantin Belousov 	res = strtol(str, &tail, 0);
647402f93eSKonstantin Belousov 	if (*tail != '\0') {
657402f93eSKonstantin Belousov 		warnx("non-numeric pid");
667402f93eSKonstantin Belousov 		return (-1);
677402f93eSKonstantin Belousov 	}
687402f93eSKonstantin Belousov 	return (res);
697402f93eSKonstantin Belousov }
707402f93eSKonstantin Belousov 
71bab3f1d0SKonstantin Belousov #ifdef PROC_KPTI_CTL
72bab3f1d0SKonstantin Belousov #define	KPTI_USAGE "|kpti"
73bab3f1d0SKonstantin Belousov #else
74bab3f1d0SKonstantin Belousov #define	KPTI_USAGE
75bab3f1d0SKonstantin Belousov #endif
76da477bcdSKonstantin Belousov #ifdef PROC_LA_CTL
77da477bcdSKonstantin Belousov #define	LA_USAGE "|la48|la57"
78da477bcdSKonstantin Belousov #else
79da477bcdSKonstantin Belousov #define	LA_USAGE
80da477bcdSKonstantin Belousov #endif
81bab3f1d0SKonstantin Belousov 
827402f93eSKonstantin Belousov static void __dead2
usage(void)837402f93eSKonstantin Belousov usage(void)
847402f93eSKonstantin Belousov {
857402f93eSKonstantin Belousov 
86c22994e3SKonstantin Belousov 	fprintf(stderr, "Usage: proccontrol -m (aslr|protmax|trace|trapcap|"
87ac8af193SKonstantin Belousov 	    "stackgap|nonewprivs|wxmap"KPTI_USAGE LA_USAGE") [-q] "
887402f93eSKonstantin Belousov 	    "[-s (enable|disable)] [-p pid | command]\n");
897402f93eSKonstantin Belousov 	exit(1);
907402f93eSKonstantin Belousov }
917402f93eSKonstantin Belousov 
927402f93eSKonstantin Belousov int
main(int argc,char * argv[])937402f93eSKonstantin Belousov main(int argc, char *argv[])
947402f93eSKonstantin Belousov {
957402f93eSKonstantin Belousov 	int arg, ch, error, mode;
967402f93eSKonstantin Belousov 	pid_t pid;
977402f93eSKonstantin Belousov 	bool enable, do_command, query;
987402f93eSKonstantin Belousov 
997402f93eSKonstantin Belousov 	mode = MODE_INVALID;
1007402f93eSKonstantin Belousov 	enable = true;
1017402f93eSKonstantin Belousov 	pid = -1;
1027402f93eSKonstantin Belousov 	query = false;
1037402f93eSKonstantin Belousov 	while ((ch = getopt(argc, argv, "m:qs:p:")) != -1) {
1047402f93eSKonstantin Belousov 		switch (ch) {
1057402f93eSKonstantin Belousov 		case 'm':
106fa50a355SKonstantin Belousov 			if (strcmp(optarg, "aslr") == 0)
107fa50a355SKonstantin Belousov 				mode = MODE_ASLR;
10846922074SKonstantin Belousov 			else if (strcmp(optarg, "protmax") == 0)
10946922074SKonstantin Belousov 				mode = MODE_PROTMAX;
110fa50a355SKonstantin Belousov 			else if (strcmp(optarg, "trace") == 0)
1117402f93eSKonstantin Belousov 				mode = MODE_TRACE;
1127402f93eSKonstantin Belousov 			else if (strcmp(optarg, "trapcap") == 0)
1137402f93eSKonstantin Belousov 				mode = MODE_TRAPCAP;
114c22994e3SKonstantin Belousov 			else if (strcmp(optarg, "stackgap") == 0)
115c22994e3SKonstantin Belousov 				mode = MODE_STACKGAP;
116acb1f126SEdward Tomasz Napierala 			else if (strcmp(optarg, "nonewprivs") == 0)
117acb1f126SEdward Tomasz Napierala 				mode = MODE_NO_NEW_PRIVS;
118ac8af193SKonstantin Belousov 			else if (strcmp(optarg, "wxmap") == 0)
119ac8af193SKonstantin Belousov 				mode = MODE_WXMAP;
120bab3f1d0SKonstantin Belousov #ifdef PROC_KPTI_CTL
121bab3f1d0SKonstantin Belousov 			else if (strcmp(optarg, "kpti") == 0)
122bab3f1d0SKonstantin Belousov 				mode = MODE_KPTI;
123bab3f1d0SKonstantin Belousov #endif
124da477bcdSKonstantin Belousov #ifdef PROC_LA_CTL
125da477bcdSKonstantin Belousov 			else if (strcmp(optarg, "la57") == 0)
126da477bcdSKonstantin Belousov 				mode = MODE_LA57;
127da477bcdSKonstantin Belousov 			else if (strcmp(optarg, "la48") == 0)
128da477bcdSKonstantin Belousov 				mode = MODE_LA48;
129da477bcdSKonstantin Belousov #endif
1307402f93eSKonstantin Belousov 			else
1317402f93eSKonstantin Belousov 				usage();
1327402f93eSKonstantin Belousov 			break;
1337402f93eSKonstantin Belousov 		case 's':
1347402f93eSKonstantin Belousov 			if (strcmp(optarg, "enable") == 0)
1357402f93eSKonstantin Belousov 				enable = true;
1367402f93eSKonstantin Belousov 			else if (strcmp(optarg, "disable") == 0)
1377402f93eSKonstantin Belousov 				enable = false;
1387402f93eSKonstantin Belousov 			else
1397402f93eSKonstantin Belousov 				usage();
1407402f93eSKonstantin Belousov 			break;
1417402f93eSKonstantin Belousov 		case 'p':
1427402f93eSKonstantin Belousov 			pid = str2pid(optarg);
1437402f93eSKonstantin Belousov 			break;
1447402f93eSKonstantin Belousov 		case 'q':
1457402f93eSKonstantin Belousov 			query = true;
1467402f93eSKonstantin Belousov 			break;
1477402f93eSKonstantin Belousov 		case '?':
1487402f93eSKonstantin Belousov 		default:
1497402f93eSKonstantin Belousov 			usage();
1507402f93eSKonstantin Belousov 			break;
1517402f93eSKonstantin Belousov 		}
1527402f93eSKonstantin Belousov 	}
1537402f93eSKonstantin Belousov 	argc -= optind;
1547402f93eSKonstantin Belousov 	argv += optind;
1557402f93eSKonstantin Belousov 	do_command = argc != 0;
1567402f93eSKonstantin Belousov 	if (do_command) {
1577402f93eSKonstantin Belousov 		if (pid != -1 || query)
1587402f93eSKonstantin Belousov 			usage();
1597402f93eSKonstantin Belousov 		pid = getpid();
1607402f93eSKonstantin Belousov 	} else if (pid == -1) {
1617402f93eSKonstantin Belousov 		pid = getpid();
1627402f93eSKonstantin Belousov 	}
1637402f93eSKonstantin Belousov 
1647402f93eSKonstantin Belousov 	if (query) {
1657402f93eSKonstantin Belousov 		switch (mode) {
166fa50a355SKonstantin Belousov 		case MODE_ASLR:
167fa50a355SKonstantin Belousov 			error = procctl(P_PID, pid, PROC_ASLR_STATUS, &arg);
168fa50a355SKonstantin Belousov 			break;
1697402f93eSKonstantin Belousov 		case MODE_TRACE:
1707402f93eSKonstantin Belousov 			error = procctl(P_PID, pid, PROC_TRACE_STATUS, &arg);
1717402f93eSKonstantin Belousov 			break;
1727402f93eSKonstantin Belousov 		case MODE_TRAPCAP:
1737402f93eSKonstantin Belousov 			error = procctl(P_PID, pid, PROC_TRAPCAP_STATUS, &arg);
1747402f93eSKonstantin Belousov 			break;
17546922074SKonstantin Belousov 		case MODE_PROTMAX:
17646922074SKonstantin Belousov 			error = procctl(P_PID, pid, PROC_PROTMAX_STATUS, &arg);
17746922074SKonstantin Belousov 			break;
178c22994e3SKonstantin Belousov 		case MODE_STACKGAP:
179c22994e3SKonstantin Belousov 			error = procctl(P_PID, pid, PROC_STACKGAP_STATUS, &arg);
180c22994e3SKonstantin Belousov 			break;
181acb1f126SEdward Tomasz Napierala 		case MODE_NO_NEW_PRIVS:
1821349891aSKonstantin Belousov 			error = procctl(P_PID, pid, PROC_NO_NEW_PRIVS_STATUS,
1831349891aSKonstantin Belousov 			    &arg);
184acb1f126SEdward Tomasz Napierala 			break;
185ac8af193SKonstantin Belousov 		case MODE_WXMAP:
186ac8af193SKonstantin Belousov 			error = procctl(P_PID, pid, PROC_WXMAP_STATUS, &arg);
187ac8af193SKonstantin Belousov 			break;
188bab3f1d0SKonstantin Belousov #ifdef PROC_KPTI_CTL
189bab3f1d0SKonstantin Belousov 		case MODE_KPTI:
190bab3f1d0SKonstantin Belousov 			error = procctl(P_PID, pid, PROC_KPTI_STATUS, &arg);
191bab3f1d0SKonstantin Belousov 			break;
192bab3f1d0SKonstantin Belousov #endif
193da477bcdSKonstantin Belousov #ifdef PROC_LA_CTL
194da477bcdSKonstantin Belousov 		case MODE_LA57:
195da477bcdSKonstantin Belousov 		case MODE_LA48:
196da477bcdSKonstantin Belousov 			error = procctl(P_PID, pid, PROC_LA_STATUS, &arg);
197da477bcdSKonstantin Belousov 			break;
198da477bcdSKonstantin Belousov #endif
1997402f93eSKonstantin Belousov 		default:
2007402f93eSKonstantin Belousov 			usage();
2017402f93eSKonstantin Belousov 			break;
2027402f93eSKonstantin Belousov 		}
2037402f93eSKonstantin Belousov 		if (error != 0)
2047402f93eSKonstantin Belousov 			err(1, "procctl status");
2057402f93eSKonstantin Belousov 		switch (mode) {
206fa50a355SKonstantin Belousov 		case MODE_ASLR:
207fa50a355SKonstantin Belousov 			switch (arg & ~PROC_ASLR_ACTIVE) {
208fa50a355SKonstantin Belousov 			case PROC_ASLR_FORCE_ENABLE:
209fa50a355SKonstantin Belousov 				printf("force enabled");
210fa50a355SKonstantin Belousov 				break;
211fa50a355SKonstantin Belousov 			case PROC_ASLR_FORCE_DISABLE:
212fa50a355SKonstantin Belousov 				printf("force disabled");
213fa50a355SKonstantin Belousov 				break;
214fa50a355SKonstantin Belousov 			case PROC_ASLR_NOFORCE:
215fa50a355SKonstantin Belousov 				printf("not forced");
216fa50a355SKonstantin Belousov 				break;
217fa50a355SKonstantin Belousov 			}
218fa50a355SKonstantin Belousov 			if ((arg & PROC_ASLR_ACTIVE) != 0)
219fa50a355SKonstantin Belousov 				printf(", active\n");
220fa50a355SKonstantin Belousov 			else
221fa50a355SKonstantin Belousov 				printf(", not active\n");
222fa50a355SKonstantin Belousov 			break;
2237402f93eSKonstantin Belousov 		case MODE_TRACE:
2247402f93eSKonstantin Belousov 			if (arg == -1)
2257402f93eSKonstantin Belousov 				printf("disabled\n");
2267402f93eSKonstantin Belousov 			else if (arg == 0)
2277402f93eSKonstantin Belousov 				printf("enabled, no debugger\n");
2287402f93eSKonstantin Belousov 			else
2297402f93eSKonstantin Belousov 				printf("enabled, traced by %d\n", arg);
2307402f93eSKonstantin Belousov 			break;
2317402f93eSKonstantin Belousov 		case MODE_TRAPCAP:
2327402f93eSKonstantin Belousov 			switch (arg) {
2337402f93eSKonstantin Belousov 			case PROC_TRAPCAP_CTL_ENABLE:
2347402f93eSKonstantin Belousov 				printf("enabled\n");
2357402f93eSKonstantin Belousov 				break;
2367402f93eSKonstantin Belousov 			case PROC_TRAPCAP_CTL_DISABLE:
2377402f93eSKonstantin Belousov 				printf("disabled\n");
2387402f93eSKonstantin Belousov 				break;
2397402f93eSKonstantin Belousov 			}
2407402f93eSKonstantin Belousov 			break;
24146922074SKonstantin Belousov 		case MODE_PROTMAX:
24246922074SKonstantin Belousov 			switch (arg & ~PROC_PROTMAX_ACTIVE) {
24346922074SKonstantin Belousov 			case PROC_PROTMAX_FORCE_ENABLE:
24446922074SKonstantin Belousov 				printf("force enabled");
24546922074SKonstantin Belousov 				break;
24646922074SKonstantin Belousov 			case PROC_PROTMAX_FORCE_DISABLE:
24746922074SKonstantin Belousov 				printf("force disabled");
24846922074SKonstantin Belousov 				break;
24946922074SKonstantin Belousov 			case PROC_PROTMAX_NOFORCE:
25046922074SKonstantin Belousov 				printf("not forced");
25146922074SKonstantin Belousov 				break;
25246922074SKonstantin Belousov 			}
25346922074SKonstantin Belousov 			if ((arg & PROC_PROTMAX_ACTIVE) != 0)
25446922074SKonstantin Belousov 				printf(", active\n");
25546922074SKonstantin Belousov 			else
25646922074SKonstantin Belousov 				printf(", not active\n");
25746922074SKonstantin Belousov 			break;
258c22994e3SKonstantin Belousov 		case MODE_STACKGAP:
259c22994e3SKonstantin Belousov 			switch (arg & (PROC_STACKGAP_ENABLE |
260c22994e3SKonstantin Belousov 			    PROC_STACKGAP_DISABLE)) {
261c22994e3SKonstantin Belousov 			case PROC_STACKGAP_ENABLE:
262c22994e3SKonstantin Belousov 				printf("enabled\n");
263c22994e3SKonstantin Belousov 				break;
264c22994e3SKonstantin Belousov 			case PROC_STACKGAP_DISABLE:
265c22994e3SKonstantin Belousov 				printf("disabled\n");
266c22994e3SKonstantin Belousov 				break;
267c22994e3SKonstantin Belousov 			}
268c22994e3SKonstantin Belousov 			switch (arg & (PROC_STACKGAP_ENABLE_EXEC |
269c22994e3SKonstantin Belousov 			    PROC_STACKGAP_DISABLE_EXEC)) {
270c22994e3SKonstantin Belousov 			case PROC_STACKGAP_ENABLE_EXEC:
271c22994e3SKonstantin Belousov 				printf("enabled after exec\n");
272c22994e3SKonstantin Belousov 				break;
273c22994e3SKonstantin Belousov 			case PROC_STACKGAP_DISABLE_EXEC:
274c22994e3SKonstantin Belousov 				printf("disabled after exec\n");
275c22994e3SKonstantin Belousov 				break;
276c22994e3SKonstantin Belousov 			}
277c22994e3SKonstantin Belousov 			break;
278acb1f126SEdward Tomasz Napierala 		case MODE_NO_NEW_PRIVS:
279acb1f126SEdward Tomasz Napierala 			switch (arg) {
280acb1f126SEdward Tomasz Napierala 			case PROC_NO_NEW_PRIVS_ENABLE:
281acb1f126SEdward Tomasz Napierala 				printf("enabled\n");
282acb1f126SEdward Tomasz Napierala 				break;
283acb1f126SEdward Tomasz Napierala 			case PROC_NO_NEW_PRIVS_DISABLE:
284acb1f126SEdward Tomasz Napierala 				printf("disabled\n");
285acb1f126SEdward Tomasz Napierala 				break;
286acb1f126SEdward Tomasz Napierala 			}
287acb1f126SEdward Tomasz Napierala 			break;
288ac8af193SKonstantin Belousov 		case MODE_WXMAP:
289ac8af193SKonstantin Belousov 			if ((arg & PROC_WX_MAPPINGS_PERMIT) != 0)
290ac8af193SKonstantin Belousov 				printf("enabled");
291ac8af193SKonstantin Belousov 			else
292ac8af193SKonstantin Belousov 				printf("disabled");
293ac8af193SKonstantin Belousov 			if ((arg & PROC_WX_MAPPINGS_DISALLOW_EXEC) != 0)
294ac8af193SKonstantin Belousov 				printf(", disabled on exec");
295ac8af193SKonstantin Belousov 			if ((arg & PROC_WXORX_ENFORCE) != 0)
296ac8af193SKonstantin Belousov 				printf(", wxorx enforced");
297ac8af193SKonstantin Belousov 			printf("\n");
298ac8af193SKonstantin Belousov 			break;
299bab3f1d0SKonstantin Belousov #ifdef PROC_KPTI_CTL
300bab3f1d0SKonstantin Belousov 		case MODE_KPTI:
301bab3f1d0SKonstantin Belousov 			switch (arg & ~PROC_KPTI_STATUS_ACTIVE) {
302bab3f1d0SKonstantin Belousov 			case PROC_KPTI_CTL_ENABLE_ON_EXEC:
303bab3f1d0SKonstantin Belousov 				printf("enabled");
304bab3f1d0SKonstantin Belousov 				break;
305bab3f1d0SKonstantin Belousov 			case PROC_KPTI_CTL_DISABLE_ON_EXEC:
306bab3f1d0SKonstantin Belousov 				printf("disabled");
307bab3f1d0SKonstantin Belousov 				break;
308bab3f1d0SKonstantin Belousov 			}
309bab3f1d0SKonstantin Belousov 			if ((arg & PROC_KPTI_STATUS_ACTIVE) != 0)
310bab3f1d0SKonstantin Belousov 				printf(", active\n");
311bab3f1d0SKonstantin Belousov 			else
312bab3f1d0SKonstantin Belousov 				printf(", not active\n");
313bab3f1d0SKonstantin Belousov 			break;
314bab3f1d0SKonstantin Belousov #endif
315da477bcdSKonstantin Belousov #ifdef PROC_LA_CTL
316da477bcdSKonstantin Belousov 		case MODE_LA57:
317da477bcdSKonstantin Belousov 		case MODE_LA48:
318da477bcdSKonstantin Belousov 			switch (arg & ~(PROC_LA_STATUS_LA48 |
319da477bcdSKonstantin Belousov 			    PROC_LA_STATUS_LA57)) {
320da477bcdSKonstantin Belousov 			case PROC_LA_CTL_LA48_ON_EXEC:
321da477bcdSKonstantin Belousov 				printf("la48 on exec");
322da477bcdSKonstantin Belousov 				break;
323da477bcdSKonstantin Belousov 			case PROC_LA_CTL_LA57_ON_EXEC:
324da477bcdSKonstantin Belousov 				printf("la57 on exec");
325da477bcdSKonstantin Belousov 				break;
326da477bcdSKonstantin Belousov 			case PROC_LA_CTL_DEFAULT_ON_EXEC:
327da477bcdSKonstantin Belousov 				printf("default on exec");
328da477bcdSKonstantin Belousov 				break;
329da477bcdSKonstantin Belousov 			}
330da477bcdSKonstantin Belousov 			if ((arg & PROC_LA_STATUS_LA48) != 0)
331da477bcdSKonstantin Belousov 				printf(", la48 active\n");
332da477bcdSKonstantin Belousov 			else if ((arg & PROC_LA_STATUS_LA57) != 0)
333da477bcdSKonstantin Belousov 				printf(", la57 active\n");
334da477bcdSKonstantin Belousov 			break;
335da477bcdSKonstantin Belousov #endif
3367402f93eSKonstantin Belousov 		}
3377402f93eSKonstantin Belousov 	} else {
3387402f93eSKonstantin Belousov 		switch (mode) {
339fa50a355SKonstantin Belousov 		case MODE_ASLR:
340fa50a355SKonstantin Belousov 			arg = enable ? PROC_ASLR_FORCE_ENABLE :
341fa50a355SKonstantin Belousov 			    PROC_ASLR_FORCE_DISABLE;
342fa50a355SKonstantin Belousov 			error = procctl(P_PID, pid, PROC_ASLR_CTL, &arg);
343fa50a355SKonstantin Belousov 			break;
3447402f93eSKonstantin Belousov 		case MODE_TRACE:
3457402f93eSKonstantin Belousov 			arg = enable ? PROC_TRACE_CTL_ENABLE :
3467402f93eSKonstantin Belousov 			    PROC_TRACE_CTL_DISABLE;
3477402f93eSKonstantin Belousov 			error = procctl(P_PID, pid, PROC_TRACE_CTL, &arg);
3487402f93eSKonstantin Belousov 			break;
3497402f93eSKonstantin Belousov 		case MODE_TRAPCAP:
3507402f93eSKonstantin Belousov 			arg = enable ? PROC_TRAPCAP_CTL_ENABLE :
3517402f93eSKonstantin Belousov 			    PROC_TRAPCAP_CTL_DISABLE;
3527402f93eSKonstantin Belousov 			error = procctl(P_PID, pid, PROC_TRAPCAP_CTL, &arg);
3537402f93eSKonstantin Belousov 			break;
35446922074SKonstantin Belousov 		case MODE_PROTMAX:
35546922074SKonstantin Belousov 			arg = enable ? PROC_PROTMAX_FORCE_ENABLE :
35646922074SKonstantin Belousov 			    PROC_PROTMAX_FORCE_DISABLE;
35746922074SKonstantin Belousov 			error = procctl(P_PID, pid, PROC_PROTMAX_CTL, &arg);
35846922074SKonstantin Belousov 			break;
359c22994e3SKonstantin Belousov 		case MODE_STACKGAP:
360c22994e3SKonstantin Belousov 			arg = enable ? PROC_STACKGAP_ENABLE_EXEC :
361c22994e3SKonstantin Belousov 			    (PROC_STACKGAP_DISABLE |
362c22994e3SKonstantin Belousov 			    PROC_STACKGAP_DISABLE_EXEC);
363c22994e3SKonstantin Belousov 			error = procctl(P_PID, pid, PROC_STACKGAP_CTL, &arg);
364c22994e3SKonstantin Belousov 			break;
365acb1f126SEdward Tomasz Napierala 		case MODE_NO_NEW_PRIVS:
366acb1f126SEdward Tomasz Napierala 			arg = enable ? PROC_NO_NEW_PRIVS_ENABLE :
367acb1f126SEdward Tomasz Napierala 			    PROC_NO_NEW_PRIVS_DISABLE;
3681349891aSKonstantin Belousov 			error = procctl(P_PID, pid, PROC_NO_NEW_PRIVS_CTL,
3691349891aSKonstantin Belousov 			    &arg);
370acb1f126SEdward Tomasz Napierala 			break;
371ac8af193SKonstantin Belousov 		case MODE_WXMAP:
372ac8af193SKonstantin Belousov 			arg = enable ? PROC_WX_MAPPINGS_PERMIT :
373ac8af193SKonstantin Belousov 			    PROC_WX_MAPPINGS_DISALLOW_EXEC;
374ac8af193SKonstantin Belousov 			error = procctl(P_PID, pid, PROC_WXMAP_CTL, &arg);
375ac8af193SKonstantin Belousov 			break;
376bab3f1d0SKonstantin Belousov #ifdef PROC_KPTI_CTL
377bab3f1d0SKonstantin Belousov 		case MODE_KPTI:
378bab3f1d0SKonstantin Belousov 			arg = enable ? PROC_KPTI_CTL_ENABLE_ON_EXEC :
379bab3f1d0SKonstantin Belousov 			    PROC_KPTI_CTL_DISABLE_ON_EXEC;
380bab3f1d0SKonstantin Belousov 			error = procctl(P_PID, pid, PROC_KPTI_CTL, &arg);
381bab3f1d0SKonstantin Belousov 			break;
382bab3f1d0SKonstantin Belousov #endif
383da477bcdSKonstantin Belousov #ifdef PROC_LA_CTL
384da477bcdSKonstantin Belousov 		case MODE_LA57:
385da477bcdSKonstantin Belousov 			arg = enable ? PROC_LA_CTL_LA57_ON_EXEC :
386da477bcdSKonstantin Belousov 			    PROC_LA_CTL_DEFAULT_ON_EXEC;
387da477bcdSKonstantin Belousov 			error = procctl(P_PID, pid, PROC_LA_CTL, &arg);
388da477bcdSKonstantin Belousov 			break;
389da477bcdSKonstantin Belousov 		case MODE_LA48:
390da477bcdSKonstantin Belousov 			arg = enable ? PROC_LA_CTL_LA48_ON_EXEC :
391da477bcdSKonstantin Belousov 			    PROC_LA_CTL_DEFAULT_ON_EXEC;
392da477bcdSKonstantin Belousov 			error = procctl(P_PID, pid, PROC_LA_CTL, &arg);
393da477bcdSKonstantin Belousov 			break;
394da477bcdSKonstantin Belousov #endif
3957402f93eSKonstantin Belousov 		default:
3967402f93eSKonstantin Belousov 			usage();
3977402f93eSKonstantin Belousov 			break;
3987402f93eSKonstantin Belousov 		}
3997402f93eSKonstantin Belousov 		if (error != 0)
4007402f93eSKonstantin Belousov 			err(1, "procctl ctl");
4017402f93eSKonstantin Belousov 		if (do_command) {
4027402f93eSKonstantin Belousov 			error = execvp(argv[0], argv);
4037402f93eSKonstantin Belousov 			err(1, "exec");
4047402f93eSKonstantin Belousov 		}
4057402f93eSKonstantin Belousov 	}
4067402f93eSKonstantin Belousov 	exit(0);
4077402f93eSKonstantin Belousov }
408