From 513d186f420176c3a1be8843fee6a42cbd57cb35 Mon Sep 17 00:00:00 2001 From: Ariadne Conill Date: Mon, 22 Nov 2021 11:06:05 -0600 Subject: [PATCH] pgrep: add support for matching against UID and RUID MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is standard functionality on every other pgrep implementation I found, namely the ones in Illumos, FreeBSD, Linux procps, and macOS. Additionally, real world scripts like pipewire-session are dependent on it being present. function old new delta pgrep_main 818 1007 +189 packed_usage 26001 26032 +31 .rodata 78544 78548 +4 ------------------------------------------------------------------------------ (add/remove: 0/0 grow/shrink: 3/0 up/down: 224/0) Total: 224 bytes Signed-off-by: Ariadne Conill --- procps/pgrep.c | 37 +++++++++++++++++++++++++++++++++---- 1 file changed, 33 insertions(+), 4 deletions(-) diff --git a/procps/pgrep.c b/procps/pgrep.c index 82e00322f..c1f7208f5 100644 --- a/procps/pgrep.c +++ b/procps/pgrep.c @@ -42,6 +42,8 @@ //usage: "\n -x Match whole name (not substring)" //usage: "\n -s Match session ID (0 for current)" //usage: "\n -P Match parent process ID" +//usage: "\n -u EUID Match against effective UID" +//usage: "\n -U UID Match against UID" //usage: //usage:#define pkill_trivial_usage //usage: "[-l|-SIGNAL] [-xfvnoe] [-s SID|-P PPID|PATTERN]" @@ -56,6 +58,8 @@ //usage: "\n -n Signal the newest process only" //usage: "\n -o Signal the oldest process only" //usage: "\n -e Display name and PID of the process being killed" +//usage: "\n -u EUID Match against effective UID" +//usage: "\n -U UID Match against UID" #include "libbb.h" #include "xregex.h" @@ -65,7 +69,7 @@ #define pkill (ENABLE_PKILL && (!ENABLE_PGREP || applet_name[1] == 'k')) enum { - /* "vlafxones:+P:+" */ + /* "vlafxoneu:U:s:+P:+" */ OPTBIT_V = 0, /* must be first, we need OPT_INVERT = 0/1 */ OPTBIT_L, OPTBIT_A, @@ -74,6 +78,8 @@ enum { OPTBIT_O, OPTBIT_N, OPTBIT_E, /* should be pkill-only, do we care? */ + OPTBIT_U, + OPTBIT_UL, OPTBIT_S, OPTBIT_P, }; @@ -88,6 +94,8 @@ enum { #define OPT_ECHO (opt & (1 << OPTBIT_E)) #define OPT_SID (opt & (1 << OPTBIT_S)) #define OPT_PPID (opt & (1 << OPTBIT_P)) +#define OPT_EUID (opt & (1 << OPTBIT_UL)) +#define OPT_RUID (opt & (1 << OPTBIT_U)) static void act(unsigned pid, char *cmd, int signo) { @@ -112,7 +120,8 @@ int pgrep_main(int argc UNUSED_PARAM, char **argv) unsigned opt; int scan_mask; int matched_pid; - int sid2match, ppid2match; + int sid2match, ppid2match, uid2match, euid2match; + char *uid_arg = NULL, *euid_arg = NULL; char *cmd_last; procps_status_t *proc; /* These are initialized to 0 */ @@ -138,7 +147,9 @@ int pgrep_main(int argc UNUSED_PARAM, char **argv) /* Parse remaining options */ ppid2match = -1; sid2match = -1; - opt = getopt32(argv, "vlafxones:+P:+", &sid2match, &ppid2match); + uid2match = -1; + euid2match = -1; + opt = getopt32(argv, "vlafxoneu:U:s:+P:+", &euid_arg, &uid_arg, &sid2match, &ppid2match); argv += optind; if (pkill && OPT_LIST) { /* -l: print the whole signal list */ @@ -154,8 +165,18 @@ int pgrep_main(int argc UNUSED_PARAM, char **argv) if (OPT_FULL) scan_mask |= PSSCAN_ARGVN; + if (euid_arg) { + scan_mask |= PSSCAN_UIDGID; + euid2match = get_ug_id(euid_arg, xuname2uid); + } + + if (uid_arg) { + scan_mask |= PSSCAN_RUIDGID; + uid2match = get_ug_id(uid_arg, xuname2uid); + } + /* One pattern is required, if no -s and no -P */ - if ((sid2match & ppid2match) < 0 && (!argv[0] || argv[1])) + if ((sid2match & ppid2match) < 0 && uid2match < 0 && euid2match < 0 && (!argv[0] || argv[1])) bb_show_usage(); if (argv[0]) @@ -177,6 +198,10 @@ int pgrep_main(int argc UNUSED_PARAM, char **argv) continue; if (sid2match >= 0 && sid2match != proc->sid) continue; + if (euid2match >= 0 && euid2match != proc->uid) + continue; + if (uid2match >= 0 && uid2match != proc->ruid) + continue; } cmdlen = -1; @@ -209,6 +234,10 @@ int pgrep_main(int argc UNUSED_PARAM, char **argv) goto got_it; if (sid2match >= 0 && sid2match != proc->sid) goto got_it; + if (euid2match >= 0 && euid2match != proc->uid) + goto got_it; + if (uid2match >= 0 && uid2match != proc->ruid) + goto got_it; } match = !argv[0]; /* if no PATTERN, then it's a match, else... */