From acd2d25a9321e09582e44812b3d095fcc6a257eb Mon Sep 17 00:00:00 2001 From: Dapeng Gao Date: Thu, 9 Jan 2025 15:15:39 +0000 Subject: [PATCH] procstat: Allow querying the names of compartments of another process --- lib/libprocstat/Symbol.map | 1 + lib/libprocstat/libprocstat.3 | 50 ++++++++++++++++++++++++++++++++- lib/libprocstat/libprocstat.c | 53 +++++++++++++++++++++++++++++++++++ lib/libprocstat/libprocstat.h | 3 ++ usr.bin/procstat/Makefile | 1 + usr.bin/procstat/procstat.1 | 19 +++++++++++++ usr.bin/procstat/procstat.c | 2 ++ usr.bin/procstat/procstat.h | 2 ++ 8 files changed, 130 insertions(+), 1 deletion(-) diff --git a/lib/libprocstat/Symbol.map b/lib/libprocstat/Symbol.map index 569884fd6240..51f61026e94b 100644 --- a/lib/libprocstat/Symbol.map +++ b/lib/libprocstat/Symbol.map @@ -51,4 +51,5 @@ FBSD_1.7 { procstat_get_revoker_epoch; procstat_get_revoker_state; procstat_getc18n; + procstat_getcompartments; }; diff --git a/lib/libprocstat/libprocstat.3 b/lib/libprocstat/libprocstat.3 index 2617a8827a6d..68ad085d1338 100644 --- a/lib/libprocstat/libprocstat.3 +++ b/lib/libprocstat/libprocstat.3 @@ -1,6 +1,12 @@ +.\" Copyright (c) 2024 Capabilities Limited .\" Copyright (c) 2011 Sergey Kandaurov .\" All rights reserved. .\" +.\" This software was developed by SRI International, the University of +.\" Cambridge Computer Laboratory (Department of Computer Science and +.\" Technology), and Capabilities Limited under Defense Advanced Research +.\" Projects Agency (DARPA) Contract No. FA8750-24-C-B047 ("DEC"). +.\" .\" Redistribution and use in source and binary forms, with or without .\" modification, are permitted provided that the following conditions .\" are met: @@ -22,7 +28,7 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.Dd April 3, 2022 +.Dd December 5, 2024 .Dt LIBPROCSTAT 3 .Os .Sh NAME @@ -47,6 +53,8 @@ .Nm procstat_getargv , .Nm procstat_getauxv , .Nm procstat_getenvv , +.Nm procstat_getc18n , +.Nm procstat_getcompartments , .Nm procstat_getfiles , .Nm procstat_getgroups , .Nm procstat_getkstack , @@ -67,6 +75,7 @@ .In sys/param.h .In sys/queue.h .In sys/socket.h +.In cheri/c18n.h .In libprocstat.h .Ft void .Fn procstat_close "struct procstat *procstat" @@ -170,6 +179,19 @@ .Fa "struct kinfo_proc *kp" .Fa "unsigned int *count" .Fc +.Ft "int" +.Fo procstat_getc18n +.Fa "struct procstat *procstat" +.Fa "struct kinfo_proc *kp" +.Fa "struct rtld_c18n_stats *stats" +.Fc +.Ft "int" +.Fo procstat_getcompartments +.Fa "struct procstat *procstat" +.Fa "struct kinfo_proc *kp" +.Fa "struct cheri_c18n_compart *comparts" +.Fa "u_int *ncompartsp" +.Fc .Ft "char **" .Fo procstat_getenvv .Fa "struct procstat *procstat" @@ -570,6 +592,28 @@ argument indicates an actual error message in case of failure. .It Li PS_FST_TYPE_SHM .Nm procstat_get_shm_info .El +.Pp +The +.Fn procstat_getc18n +function retrieves +compartmentalization (\c +.Xr c18n ) +statistics for a target process, including its number of intra-process +compartments, instantiated trampolines, and other values. +The +.Fn procstat_getcompartments +function retrieves a compartment list for target process. +The +.Fa comparts +argument is a pointer to a caller-allocated array of +.Ft struct cheri_c18n_compart +entries of size +.Fa *ncompartsp +passed by reference. +On return, the compartment list is terminated with a compartment ID of +.Dv CHERI_C18N_COMPART_LAST . +If a terminating entry is not found in the returned array, then there was +insufficient space, and the caller should allocate a larger array and retry. .Sh SEE ALSO .Xr fstat 1 , .Xr fuser 1 , @@ -583,6 +627,7 @@ argument indicates an actual error message in case of failure. .Xr sysctl 3 , .Xr pts 4 , .Xr core 5 , +.Xr c18n 7 , .Xr vnode 9 .Sh HISTORY The @@ -595,6 +640,9 @@ The .Nm libprocstat library was written by .An Stanislav Sedov Aq Mt stas@FreeBSD.org . +.Xr c18n 3 -related +monitoring APIs were added by +.An Robert N. M. Watson Aq Mt rwatson@FreeBSD.org . .Pp This manual page was written by .An Sergey Kandaurov Aq Mt pluknet@FreeBSD.org . diff --git a/lib/libprocstat/libprocstat.c b/lib/libprocstat/libprocstat.c index 94b163430a90..e9cd0865a496 100644 --- a/lib/libprocstat/libprocstat.c +++ b/lib/libprocstat/libprocstat.c @@ -1,11 +1,17 @@ /*- * SPDX-License-Identifier: BSD-4-Clause * + * Copyright (c) 2024 Capabilities Limited * Copyright (c) 2017 Dell EMC * Copyright (c) 2009 Stanislav Sedov * Copyright (c) 1988, 1993 * The Regents of the University of California. All rights reserved. * + * This software was developed by SRI International, the University of + * Cambridge Computer Laboratory (Department of Computer Science and + * Technology), and Capabilities Limited under Defense Advanced Research + * Projects Agency (DARPA) Contract No. FA8750-24-C-B047 ("DEC"). + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: @@ -399,6 +405,53 @@ procstat_getc18n(struct procstat *procstat, struct kinfo_proc *kp, return (-1); } +int +procstat_getcompartments(struct procstat *procstat, struct kinfo_proc *kp, + struct cheri_c18n_compart *comparts, u_int *ncompartsp) +{ + int name[4]; + size_t size; + + if (comparts == NULL || ncompartsp == NULL) + goto out; + + switch (procstat->type) { + case PROCSTAT_KVM: + warnx("kvm method is not supported"); + goto out; + + case PROCSTAT_SYSCTL: + break; + + case PROCSTAT_CORE: + warnx("core method is not supported"); + goto out; + + default: + warnx("unknown access method: %d", procstat->type); + goto out; + } + + name[0] = CTL_KERN; + name[1] = KERN_PROC; + name[2] = KERN_PROC_C18N_COMPARTS; + name[3] = kp->ki_pid; + size = *ncompartsp * sizeof(*comparts); + if (sysctl(name, nitems(name), comparts, &size, NULL, 0) != 0) { + if (errno != ESRCH && errno != EPERM && errno != ENOEXEC) + warn("sysctl(kern.proc.c18n_compartments)"); + goto out; + } + if (size % sizeof(*comparts) != 0) + goto out; + *ncompartsp = size / sizeof(*comparts); + return (0); + +out: + *ncompartsp = 0; + return (-1); +} + struct filestat_list * procstat_getfiles(struct procstat *procstat, struct kinfo_proc *kp, int mmapped) { diff --git a/lib/libprocstat/libprocstat.h b/lib/libprocstat/libprocstat.h index bb43ef88496d..60d771d5097e 100644 --- a/lib/libprocstat/libprocstat.h +++ b/lib/libprocstat/libprocstat.h @@ -217,6 +217,9 @@ void procstat_freevmmap(struct procstat *procstat, struct advlock_list *procstat_getadvlock(struct procstat *procstat); int procstat_getc18n(struct procstat *procstat, struct kinfo_proc *kp, struct rtld_c18n_stats *stats); +int procstat_getcompartments(struct procstat *procstat, + struct kinfo_proc *kp, struct cheri_c18n_compart *comparts, + u_int *ncomparts); struct filestat_list *procstat_getfiles(struct procstat *procstat, struct kinfo_proc *kp, int mmapped); struct kinfo_proc *procstat_getprocs(struct procstat *procstat, diff --git a/usr.bin/procstat/Makefile b/usr.bin/procstat/Makefile index c7607d5e295f..2c71b6ee29c9 100644 --- a/usr.bin/procstat/Makefile +++ b/usr.bin/procstat/Makefile @@ -10,6 +10,7 @@ SRCS= procstat.c \ procstat_bin.c \ procstat_c18n.c \ procstat_cheri.c \ + procstat_compartments.c \ procstat_cred.c \ procstat_cs.c \ procstat_files.c \ diff --git a/usr.bin/procstat/procstat.1 b/usr.bin/procstat/procstat.1 index fc938dde6084..511ecc151876 100644 --- a/usr.bin/procstat/procstat.1 +++ b/usr.bin/procstat/procstat.1 @@ -176,6 +176,10 @@ Display CHERI-specific information about the process. If the .Fl v flag is passed then extra information is shown. +.It Ar compartments +Display information on +.Xr c18n 7 +compartments within the process. .It Ar environment | Fl e Display environment variables for the process. .Pp @@ -380,6 +384,21 @@ revoker initialized, epoch open .It closing revoker finishing an epoch .El +.Ss Compartment List +Display the list of +.Xr c18n 7 +compartments within a process: +.Pp +.Bl -tag -width CNAME -compact +.It PID +process ID +.It COMM +command +.It CID +compartment ID +.It CNAME +compartment name +.El .Ss Environment Variables Display the process ID, command, and environment variables: .Pp diff --git a/usr.bin/procstat/procstat.c b/usr.bin/procstat/procstat.c index c855e4407d03..54c29a3fce46 100644 --- a/usr.bin/procstat/procstat.c +++ b/usr.bin/procstat/procstat.c @@ -97,6 +97,8 @@ static const struct procstat_cmd cmd_table[] = { PS_CMP_NORMAL }, { "cheri", "cheri", "[-v]", &procstat_cheri, &cmdopt_verbose, PS_CMP_NORMAL }, + { "compartments", "compartments", NULL, &procstat_compartments, + cmdopt_none, PS_CMP_NORMAL }, { "cpuset", "cs", NULL, &procstat_cs, &cmdopt_cpuset, PS_CMP_NORMAL }, { "cs", "cs", NULL, &procstat_cs, &cmdopt_cpuset, PS_CMP_NORMAL }, { "credential", "credentials", NULL, &procstat_cred, &cmdopt_none, diff --git a/usr.bin/procstat/procstat.h b/usr.bin/procstat/procstat.h index 36738e24f7d2..aaf08e0549c1 100644 --- a/usr.bin/procstat/procstat.h +++ b/usr.bin/procstat/procstat.h @@ -62,6 +62,8 @@ void procstat_basic(struct procstat *prstat, struct kinfo_proc *kipp); void procstat_bin(struct procstat *prstat, struct kinfo_proc *kipp); void procstat_c18n(struct procstat *prstat, struct kinfo_proc *kipp); void procstat_cheri(struct procstat *prstat, struct kinfo_proc *kipp); +void procstat_compartments(struct procstat *procstat, + struct kinfo_proc *kipp); void procstat_cred(struct procstat *prstat, struct kinfo_proc *kipp); void procstat_cs(struct procstat *prstat, struct kinfo_proc *kipp); void procstat_env(struct procstat *prstat, struct kinfo_proc *kipp);