aboutsummaryrefslogtreecommitdiffstats
path: root/main/busybox/0001-pgrep-add-support-for-matching-against-UID-and-RUID.patch
blob: 7abfb09b763fd7117e75bb44ad333cad39b320b2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
From 648255c510f9a3f668651842b58798f07ad4c64a Mon Sep 17 00:00:00 2001
From: Ariadne Conill <ariadne@dereferenced.org>
Date: Mon, 22 Nov 2021 18:33:02 -0600
Subject: [PATCH] pgrep: add support for matching against UID and RUID

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 <ariadne@dereferenced.org>
---
 procps/pgrep.c | 37 +++++++++++++++++++++++++++++++++----
 1 file changed, 33 insertions(+), 4 deletions(-)

diff --git a/procps/pgrep.c b/procps/pgrep.c
index 6d25c247e..6a12ac23b 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] [-xfvno] [-s SID|-P PPID|PATTERN]"
@@ -55,6 +57,8 @@
 //usage:     "\n	-v	Negate the match"
 //usage:     "\n	-n	Signal the newest process only"
 //usage:     "\n	-o	Signal the oldest process only"
+//usage:     "\n	-u EUID Match against effective UID"
+//usage:     "\n	-U UID  Match against UID"
 
 #include "libbb.h"
 #include "xregex.h"
@@ -64,7 +68,7 @@
 #define pkill (ENABLE_PKILL && (!ENABLE_PGREP || applet_name[1] == 'k'))
 
 enum {
-	/* "vlafxons:+P:+" */
+	/* "vlafxonu:U:s:+P:+" */
 	OPTBIT_V = 0, /* must be first, we need OPT_INVERT = 0/1 */
 	OPTBIT_L,
 	OPTBIT_A,
@@ -72,6 +76,8 @@ enum {
 	OPTBIT_X,
 	OPTBIT_O,
 	OPTBIT_N,
+	OPTBIT_U,
+	OPTBIT_UL,
 	OPTBIT_S,
 	OPTBIT_P,
 };
@@ -85,6 +91,8 @@ enum {
 #define OPT_LAST	(opt & (1 << OPTBIT_N))
 #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)
 {
@@ -105,7 +113,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 */
@@ -131,7 +140,9 @@ int pgrep_main(int argc UNUSED_PARAM, char **argv)
 	/* Parse remaining options */
 	ppid2match = -1;
 	sid2match = -1;
-	opt = getopt32(argv, "vlafxons:+P:+", &sid2match, &ppid2match);
+	uid2match = -1;
+	euid2match = -1;
+	opt = getopt32(argv, "vlafxonu:U:s:+P:+", &euid_arg, &uid_arg, &sid2match, &ppid2match);
 	argv += optind;
 
 	if (pkill && OPT_LIST) { /* -l: print the whole signal list */
@@ -147,8 +158,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])
@@ -170,6 +191,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;
@@ -202,6 +227,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... */
-- 
2.34.0