Changeset View
Changeset View
Standalone View
Standalone View
usr.bin/proccontrol/proccontrol.c
Show All 33 Lines | |||||
#include <err.h> | #include <err.h> | ||||
#include <stdbool.h> | #include <stdbool.h> | ||||
#include <stdio.h> | #include <stdio.h> | ||||
#include <stdlib.h> | #include <stdlib.h> | ||||
#include <string.h> | #include <string.h> | ||||
#include <unistd.h> | #include <unistd.h> | ||||
enum { | enum { | ||||
MODE_ASLR, | |||||
MODE_INVALID, | MODE_INVALID, | ||||
MODE_TRACE, | MODE_TRACE, | ||||
MODE_TRAPCAP, | MODE_TRAPCAP, | ||||
}; | }; | ||||
static pid_t | static pid_t | ||||
str2pid(const char *str) | str2pid(const char *str) | ||||
{ | { | ||||
pid_t res; | pid_t res; | ||||
char *tail; | char *tail; | ||||
res = strtol(str, &tail, 0); | res = strtol(str, &tail, 0); | ||||
if (*tail != '\0') { | if (*tail != '\0') { | ||||
warnx("non-numeric pid"); | warnx("non-numeric pid"); | ||||
return (-1); | return (-1); | ||||
} | } | ||||
return (res); | return (res); | ||||
} | } | ||||
static void __dead2 | static void __dead2 | ||||
usage(void) | usage(void) | ||||
{ | { | ||||
fprintf(stderr, "Usage: proccontrol -m (trace|trapcap) [-q] " | fprintf(stderr, "Usage: proccontrol -m (aslr|trace|trapcap) [-q] " | ||||
emaste: The usage at least should be in alpha order, which will match the eventual man page. | |||||
"[-s (enable|disable)] [-p pid | command]\n"); | "[-s (enable|disable)] [-p pid | command]\n"); | ||||
exit(1); | exit(1); | ||||
} | } | ||||
int | int | ||||
main(int argc, char *argv[]) | main(int argc, char *argv[]) | ||||
{ | { | ||||
int arg, ch, error, mode; | int arg, ch, error, mode; | ||||
pid_t pid; | pid_t pid; | ||||
bool enable, do_command, query; | bool enable, do_command, query; | ||||
mode = MODE_INVALID; | mode = MODE_INVALID; | ||||
enable = true; | enable = true; | ||||
pid = -1; | pid = -1; | ||||
query = false; | query = false; | ||||
while ((ch = getopt(argc, argv, "m:qs:p:")) != -1) { | while ((ch = getopt(argc, argv, "m:qs:p:")) != -1) { | ||||
switch (ch) { | switch (ch) { | ||||
case 'm': | case 'm': | ||||
if (strcmp(optarg, "trace") == 0) | if (strcmp(optarg, "aslr") == 0) | ||||
mode = MODE_ASLR; | |||||
else if (strcmp(optarg, "trace") == 0) | |||||
Not Done Inline ActionsI think I missed earlier discussion of this, but it seems wrong that we don't support multiple -m values. markj: I think I missed earlier discussion of this, but it seems wrong that we don't support multiple… | |||||
Done Inline ActionsWe do not need to, you can chain proccontrol, same as e.g. nice/nohup/sudo etc. kib: We do not need to, you can chain proccontrol, same as e.g. nice/nohup/sudo etc. | |||||
mode = MODE_TRACE; | mode = MODE_TRACE; | ||||
else if (strcmp(optarg, "trapcap") == 0) | else if (strcmp(optarg, "trapcap") == 0) | ||||
mode = MODE_TRAPCAP; | mode = MODE_TRAPCAP; | ||||
else | else | ||||
usage(); | usage(); | ||||
break; | break; | ||||
case 's': | case 's': | ||||
if (strcmp(optarg, "enable") == 0) | if (strcmp(optarg, "enable") == 0) | ||||
Show All 23 Lines | if (pid != -1 || query) | ||||
usage(); | usage(); | ||||
pid = getpid(); | pid = getpid(); | ||||
} else if (pid == -1) { | } else if (pid == -1) { | ||||
pid = getpid(); | pid = getpid(); | ||||
} | } | ||||
if (query) { | if (query) { | ||||
switch (mode) { | switch (mode) { | ||||
case MODE_ASLR: | |||||
error = procctl(P_PID, pid, PROC_ASLR_STATUS, &arg); | |||||
break; | |||||
case MODE_TRACE: | case MODE_TRACE: | ||||
error = procctl(P_PID, pid, PROC_TRACE_STATUS, &arg); | error = procctl(P_PID, pid, PROC_TRACE_STATUS, &arg); | ||||
break; | break; | ||||
case MODE_TRAPCAP: | case MODE_TRAPCAP: | ||||
error = procctl(P_PID, pid, PROC_TRAPCAP_STATUS, &arg); | error = procctl(P_PID, pid, PROC_TRAPCAP_STATUS, &arg); | ||||
break; | break; | ||||
default: | default: | ||||
usage(); | usage(); | ||||
break; | break; | ||||
} | } | ||||
if (error != 0) | if (error != 0) | ||||
err(1, "procctl status"); | err(1, "procctl status"); | ||||
switch (mode) { | switch (mode) { | ||||
case MODE_ASLR: | |||||
switch (arg & ~PROC_ASLR_ACTIVE) { | |||||
case PROC_ASLR_FORCE_ENABLE: | |||||
printf("force enabled"); | |||||
break; | |||||
case PROC_ASLR_FORCE_DISABLE: | |||||
printf("force disabled"); | |||||
break; | |||||
case PROC_ASLR_NOFORCE: | |||||
printf("not forced"); | |||||
break; | |||||
} | |||||
if ((arg & PROC_ASLR_ACTIVE) != 0) | |||||
printf(", active\n"); | |||||
else | |||||
printf(", not active\n"); | |||||
break; | |||||
case MODE_TRACE: | case MODE_TRACE: | ||||
if (arg == -1) | if (arg == -1) | ||||
printf("disabled\n"); | printf("disabled\n"); | ||||
else if (arg == 0) | else if (arg == 0) | ||||
printf("enabled, no debugger\n"); | printf("enabled, no debugger\n"); | ||||
else | else | ||||
printf("enabled, traced by %d\n", arg); | printf("enabled, traced by %d\n", arg); | ||||
break; | break; | ||||
case MODE_TRAPCAP: | case MODE_TRAPCAP: | ||||
switch (arg) { | switch (arg) { | ||||
case PROC_TRAPCAP_CTL_ENABLE: | case PROC_TRAPCAP_CTL_ENABLE: | ||||
printf("enabled\n"); | printf("enabled\n"); | ||||
break; | break; | ||||
case PROC_TRAPCAP_CTL_DISABLE: | case PROC_TRAPCAP_CTL_DISABLE: | ||||
printf("disabled\n"); | printf("disabled\n"); | ||||
break; | break; | ||||
} | } | ||||
break; | break; | ||||
} | } | ||||
} else { | } else { | ||||
switch (mode) { | switch (mode) { | ||||
case MODE_ASLR: | |||||
arg = enable ? PROC_ASLR_FORCE_ENABLE : | |||||
PROC_ASLR_FORCE_DISABLE; | |||||
error = procctl(P_PID, pid, PROC_ASLR_CTL, &arg); | |||||
break; | |||||
case MODE_TRACE: | case MODE_TRACE: | ||||
arg = enable ? PROC_TRACE_CTL_ENABLE : | arg = enable ? PROC_TRACE_CTL_ENABLE : | ||||
PROC_TRACE_CTL_DISABLE; | PROC_TRACE_CTL_DISABLE; | ||||
error = procctl(P_PID, pid, PROC_TRACE_CTL, &arg); | error = procctl(P_PID, pid, PROC_TRACE_CTL, &arg); | ||||
break; | break; | ||||
case MODE_TRAPCAP: | case MODE_TRAPCAP: | ||||
arg = enable ? PROC_TRAPCAP_CTL_ENABLE : | arg = enable ? PROC_TRAPCAP_CTL_ENABLE : | ||||
PROC_TRAPCAP_CTL_DISABLE; | PROC_TRAPCAP_CTL_DISABLE; | ||||
Show All 15 Lines |
The usage at least should be in alpha order, which will match the eventual man page.