mirror of
https://git.FreeBSD.org/src.git
synced 2025-02-06 18:29:47 +00:00
Introduce a new sysctl process mib, kern.proc.groups which adds the
ability to retrieve the group list of each process. Modify procstat's -s option to query this mib when the kinfo_proc reports that the field has been truncated. If the mib does not exist, fall back to the truncated list. Reviewed by: rwatson Approved by: re (kib) MFC after: 2 weeks
This commit is contained in:
parent
5f60e483c8
commit
254d03c508
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=195853
@ -1826,6 +1826,43 @@ repeat:
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* This sysctl allows a process to retrieve the full list of groups from
|
||||
* itself or another process.
|
||||
*/
|
||||
static int
|
||||
sysctl_kern_proc_groups(SYSCTL_HANDLER_ARGS)
|
||||
{
|
||||
pid_t *pidp = (pid_t *)arg1;
|
||||
unsigned int arglen = arg2;
|
||||
struct proc *p;
|
||||
struct ucred *cred;
|
||||
int error;
|
||||
|
||||
if (arglen != 1)
|
||||
return (EINVAL);
|
||||
if (*pidp == -1) { /* -1 means this process */
|
||||
p = req->td->td_proc;
|
||||
} else {
|
||||
p = pfind(*pidp);
|
||||
if (p == NULL)
|
||||
return (ESRCH);
|
||||
if ((error = p_cansee(curthread, p)) != 0) {
|
||||
PROC_UNLOCK(p);
|
||||
return (error);
|
||||
}
|
||||
}
|
||||
|
||||
cred = crhold(p->p_ucred);
|
||||
if (*pidp != -1)
|
||||
PROC_UNLOCK(p);
|
||||
|
||||
error = SYSCTL_OUT(req, cred->cr_groups,
|
||||
cred->cr_ngroups * sizeof(gid_t));
|
||||
crfree(cred);
|
||||
return (error);
|
||||
}
|
||||
|
||||
SYSCTL_NODE(_kern, KERN_PROC, proc, CTLFLAG_RD, 0, "Process table");
|
||||
|
||||
SYSCTL_PROC(_kern_proc, KERN_PROC_ALL, all, CTLFLAG_RD|CTLTYPE_STRUCT|
|
||||
@ -1910,3 +1947,6 @@ static SYSCTL_NODE(_kern_proc, KERN_PROC_VMMAP, vmmap, CTLFLAG_RD |
|
||||
static SYSCTL_NODE(_kern_proc, KERN_PROC_KSTACK, kstack, CTLFLAG_RD |
|
||||
CTLFLAG_MPSAFE, sysctl_kern_proc_kstack, "Process kernel stacks");
|
||||
#endif
|
||||
|
||||
static SYSCTL_NODE(_kern_proc, KERN_PROC_GROUPS, groups, CTLFLAG_RD |
|
||||
CTLFLAG_MPSAFE, sysctl_kern_proc_groups, "Process groups");
|
||||
|
@ -486,6 +486,7 @@ TAILQ_HEAD(sysctl_ctx_list, sysctl_ctx_entry);
|
||||
*/
|
||||
#define KERN_PROC_VMMAP 32 /* VM map entries for process */
|
||||
#define KERN_PROC_FILEDESC 33 /* File descriptors for process */
|
||||
#define KERN_PROC_GROUPS 34 /* process groups */
|
||||
|
||||
/*
|
||||
* KERN_IPC identifiers
|
||||
|
@ -31,7 +31,9 @@
|
||||
#include <sys/user.h>
|
||||
|
||||
#include <err.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "procstat.h"
|
||||
|
||||
@ -39,6 +41,10 @@ void
|
||||
procstat_cred(pid_t pid, struct kinfo_proc *kipp)
|
||||
{
|
||||
int i;
|
||||
int mib[4];
|
||||
int ngroups;
|
||||
size_t len;
|
||||
gid_t *groups = NULL;
|
||||
|
||||
if (!hflag)
|
||||
printf("%5s %-16s %5s %5s %5s %5s %5s %5s %-20s\n", "PID",
|
||||
@ -53,7 +59,39 @@ procstat_cred(pid_t pid, struct kinfo_proc *kipp)
|
||||
printf("%5d ", kipp->ki_groups[0]);
|
||||
printf("%5d ", kipp->ki_rgid);
|
||||
printf("%5d ", kipp->ki_svgid);
|
||||
for (i = 0; i < kipp->ki_ngroups; i++)
|
||||
printf("%s%d", (i > 0) ? "," : "", kipp->ki_groups[i]);
|
||||
|
||||
/*
|
||||
* We may have too many groups to fit in kinfo_proc's statically
|
||||
* sized storage. If that occurs, attempt to retrieve them via
|
||||
* sysctl.
|
||||
*/
|
||||
if (kipp->ki_cr_flags & KI_CRF_GRP_OVERFLOW) {
|
||||
mib[0] = CTL_KERN;
|
||||
mib[1] = KERN_PROC;
|
||||
mib[2] = KERN_PROC_GROUPS;
|
||||
mib[3] = pid;
|
||||
|
||||
ngroups = sysconf(_SC_NGROUPS_MAX) + 1;
|
||||
len = ngroups * sizeof(gid_t);
|
||||
if((groups = malloc(len)) == NULL)
|
||||
err(-1, "malloc");
|
||||
|
||||
if (sysctl(mib, 4, groups, &len, NULL, 0) == -1) {
|
||||
warn("sysctl: kern.proc.groups: %d "
|
||||
"group list truncated", pid);
|
||||
free(groups);
|
||||
groups = NULL;
|
||||
}
|
||||
ngroups = len / sizeof(gid_t);
|
||||
}
|
||||
if (groups == NULL) {
|
||||
ngroups = kipp->ki_ngroups;
|
||||
groups = kipp->ki_groups;
|
||||
}
|
||||
for (i = 0; i < ngroups; i++)
|
||||
printf("%s%d", (i > 0) ? "," : "", groups[i]);
|
||||
if (groups != kipp->ki_groups)
|
||||
free(groups);
|
||||
|
||||
printf("\n");
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user