From 4b88f1aac5b63dd4e9287a773a6240d69ac3db17 Mon Sep 17 00:00:00 2001 From: Brooks Davis Date: Thu, 5 Oct 2023 22:13:40 +0100 Subject: [PATCH] procstat auxv: show capabilities For ELF auxargs that are pointers, print more capability information in verbose mode. --- usr.bin/procstat/procstat.1 | 8 +++- usr.bin/procstat/procstat.c | 2 +- usr.bin/procstat/procstat_auxv.c | 64 ++++++++++++++++++++------------ 3 files changed, 48 insertions(+), 26 deletions(-) diff --git a/usr.bin/procstat/procstat.1 b/usr.bin/procstat/procstat.1 index 4693bbc7611d..4de4e76abe26 100644 --- a/usr.bin/procstat/procstat.1 +++ b/usr.bin/procstat/procstat.1 @@ -23,7 +23,7 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.Dd April 7, 2022 +.Dd October 13, 2023 .Dt PROCSTAT 1 .Os .Sh NAME @@ -241,6 +241,12 @@ If the flag is passed then extra information is shown. .It Ar auxv | Fl x Display ELF auxiliary vector for the process. +.Pp +If the +.Fl v +subcommand option is used and the target process's ABI is a CHERI +pure-capabilty ABI, then print capability bounds and permissions for +pointer arguments. .It Ar pargs Display arguments for the process. .It Ar penv diff --git a/usr.bin/procstat/procstat.c b/usr.bin/procstat/procstat.c index 1009360cd19d..4825e9a43f2f 100644 --- a/usr.bin/procstat/procstat.c +++ b/usr.bin/procstat/procstat.c @@ -89,7 +89,7 @@ static const struct procstat_cmd cmd_table[] = { PS_CMP_PLURAL | PS_CMP_SUBSTR | PS_MODE_NO_KINFO_PROC }, { "argument", "arguments", NULL, &procstat_args, &cmdopt_none, PS_CMP_PLURAL | PS_CMP_SUBSTR }, - { "auxv", "auxv", NULL, &procstat_auxv, &cmdopt_none, PS_CMP_NORMAL }, + { "auxv", "auxv", "[-v]", &procstat_auxv, &cmdopt_verbose, PS_CMP_NORMAL }, { "basic", "basic", NULL, &procstat_basic, &cmdopt_none, PS_CMP_NORMAL }, { "binary", "binary", NULL, &procstat_bin, &cmdopt_none, diff --git a/usr.bin/procstat/procstat_auxv.c b/usr.bin/procstat/procstat_auxv.c index 2423bda94c4a..33e13294a188 100644 --- a/usr.bin/procstat/procstat_auxv.c +++ b/usr.bin/procstat/procstat_auxv.c @@ -46,6 +46,8 @@ #include +#include + #include #include #include @@ -56,6 +58,20 @@ #include "procstat.h" +static const char * +fmt_ptr(void *ptr) +{ + static char ptrstr[128]; + +#ifdef __CHERI_PURE_CAPABILITY__ + if ((procstat_opts & PS_OPT_VERBOSE) != 0) + strfcap(ptrstr, sizeof(ptrstr), "%T%C", (uintcap_t)ptr); + else +#endif + snprintf(ptrstr, sizeof(ptrstr), "%p", ptr); + return (ptrstr); +} + void procstat_auxv(struct procstat *procstat, struct kinfo_proc *kipp) { @@ -87,8 +103,8 @@ procstat_auxv(struct procstat *procstat, struct kinfo_proc *kipp) prefix, "AT_EXECFD", (long)auxv[i].a_un.a_val); break; case AT_PHDR: - xo_emit("{dw:/%s}{Lw:/%-16s/%s}{:AT_PHDR/%p}\n", - prefix, "AT_PHDR", auxv[i].a_un.a_ptr); + xo_emit("{dw:/%s}{Lw:/%-16s/%s}{:AT_PHDR/%s}\n", + prefix, "AT_PHDR", fmt_ptr(auxv[i].a_un.a_ptr)); break; case AT_PHENT: xo_emit("{dw:/%s}{Lw:/%-16s/%s}{:AT_PHENT/%ld}\n", @@ -103,16 +119,16 @@ procstat_auxv(struct procstat *procstat, struct kinfo_proc *kipp) prefix, "AT_PAGESZ", (long)auxv[i].a_un.a_val); break; case AT_BASE: - xo_emit("{dw:/%s}{Lw:/%-16s/%s}{:AT_BASE/%p}\n", - prefix, "AT_BASE", auxv[i].a_un.a_ptr); + xo_emit("{dw:/%s}{Lw:/%-16s/%s}{:AT_BASE/%s}\n", + prefix, "AT_BASE", fmt_ptr(auxv[i].a_un.a_ptr)); break; case AT_FLAGS: xo_emit("{dw:/%s}{Lw:/%-16s/%s}{:AT_FLAGS/%#lx}\n", prefix, "AT_FLAGS", (u_long)auxv[i].a_un.a_val); break; case AT_ENTRY: - xo_emit("{dw:/%s}{Lw:/%-16s/%s}{:AT_ENTRY/%p}\n", - prefix, "AT_ENTRY", auxv[i].a_un.a_ptr); + xo_emit("{dw:/%s}{Lw:/%-16s/%s}{:AT_ENTRY/%s}\n", + prefix, "AT_ENTRY", fmt_ptr(auxv[i].a_un.a_ptr)); break; #ifdef AT_NOTELF case AT_NOTELF: @@ -145,12 +161,12 @@ procstat_auxv(struct procstat *procstat, struct kinfo_proc *kipp) break; #endif case AT_EXECPATH: - xo_emit("{dw:/%s}{Lw:/%-16s/%s}{:AT_EXECPATH/%p}\n", - prefix, "AT_EXECPATH", auxv[i].a_un.a_ptr); + xo_emit("{dw:/%s}{Lw:/%-16s/%s}{:AT_EXECPATH/%s}\n", + prefix, "AT_EXECPATH", fmt_ptr(auxv[i].a_un.a_ptr)); break; case AT_CANARY: - xo_emit("{dw:/%s}{Lw:/%-16s/%s}{:AT_CANARY/%p}\n", - prefix, "AT_CANARY", auxv[i].a_un.a_ptr); + xo_emit("{dw:/%s}{Lw:/%-16s/%s}{:AT_CANARY/%s}\n", + prefix, "AT_CANARY", fmt_ptr(auxv[i].a_un.a_ptr)); break; case AT_CANARYLEN: xo_emit("{dw:/%s}{Lw:/%-16s/%s}{:AT_CANARYLEN/%ld}\n", @@ -165,8 +181,8 @@ procstat_auxv(struct procstat *procstat, struct kinfo_proc *kipp) prefix, "AT_NCPUS", (long)auxv[i].a_un.a_val); break; case AT_PAGESIZES: - xo_emit("{dw:/%s}{Lw:/%-16s/%s}{:AT_PAGESIZES/%p}\n", - prefix, "AT_PAGESIZES", auxv[i].a_un.a_ptr); + xo_emit("{dw:/%s}{Lw:/%-16s/%s}{:AT_PAGESIZES/%s}\n", + prefix, "AT_PAGESIZES", fmt_ptr(auxv[i].a_un.a_ptr)); break; case AT_PAGESIZESLEN: xo_emit("{dw:/%s}{Lw:/%-16s/%s}" @@ -185,8 +201,8 @@ procstat_auxv(struct procstat *procstat, struct kinfo_proc *kipp) break; #ifdef AT_TIMEKEEP case AT_TIMEKEEP: - xo_emit("{dw:/%s}{Lw:/%-16s/%s}{:AT_TIMEKEEP/%p}\n", - prefix, "AT_TIMEKEEP", auxv[i].a_un.a_ptr); + xo_emit("{dw:/%s}{Lw:/%-16s/%s}{:AT_TIMEKEEP/%s}\n", + prefix, "AT_TIMEKEEP", fmt_ptr(auxv[i].a_un.a_ptr)); break; #endif #ifdef AT_EHDRFLAGS @@ -221,8 +237,8 @@ procstat_auxv(struct procstat *procstat, struct kinfo_proc *kipp) #endif #ifdef AT_ARGV case AT_ARGV: - xo_emit("{dw:/%s}{Lw:/%-16s/%s}{:AT_ARGV/%p}\n", - prefix, "AT_ARGV", auxv[i].a_un.a_ptr); + xo_emit("{dw:/%s}{Lw:/%-16s/%s}{:AT_ARGV/%s}\n", + prefix, "AT_ARGV", fmt_ptr(auxv[i].a_un.a_ptr)); break; #endif #ifdef AT_ENVC @@ -233,26 +249,26 @@ procstat_auxv(struct procstat *procstat, struct kinfo_proc *kipp) #endif #ifdef AT_ENVV case AT_ENVV: - xo_emit("{dw:/%s}{Lw:/%-16s/%s}{:AT_ENVV/%p}\n", - prefix, "AT_ENVV", auxv[i].a_un.a_ptr); + xo_emit("{dw:/%s}{Lw:/%-16s/%s}{:AT_ENVV/%s}\n", + prefix, "AT_ENVV", fmt_ptr(auxv[i].a_un.a_ptr)); break; #endif #ifdef AT_PS_STRINGS case AT_PS_STRINGS: - xo_emit("{dw:/%s}{Lw:/%-16s/%s}{:AT_PS_STRINGS/%p}\n", - prefix, "AT_PS_STRINGS", auxv[i].a_un.a_ptr); + xo_emit("{dw:/%s}{Lw:/%-16s/%s}{:AT_PS_STRINGS/%s}\n", + prefix, "AT_PS_STRINGS", fmt_ptr(auxv[i].a_un.a_ptr)); break; #endif #ifdef AT_FXRNG case AT_FXRNG: - xo_emit("{dw:/%s}{Lw:/%-16s/%s}{:AT_FXRNG/%p}\n", - prefix, "AT_FXRNG", auxv[i].a_un.a_ptr); + xo_emit("{dw:/%s}{Lw:/%-16s/%s}{:AT_FXRNG/%s}\n", + prefix, "AT_FXRNG", fmt_ptr(auxv[i].a_un.a_ptr)); break; #endif #ifdef AT_KPRELOAD case AT_KPRELOAD: - xo_emit("{dw:/%s}{Lw:/%-16s/%s}{:AT_KPRELOAD/%p}\n", - prefix, "AT_KPRELOAD", auxv[i].a_un.a_ptr); + xo_emit("{dw:/%s}{Lw:/%-16s/%s}{:AT_KPRELOAD/%s}\n", + prefix, "AT_KPRELOAD", fmt_ptr(auxv[i].a_un.a_ptr)); break; #endif #ifdef AT_USRSTACKBASE