"Fossies" - the Fresh Open Source Software Archive 
Member "chkrootkit-0.55/chkproc.c" (8 Mar 2021, 10056 Bytes) of package /linux/misc/chkrootkit-0.55.tar.gz:
As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style:
standard) with prefixed line numbers and
code folding option.
Alternatively you can here
view or
download the uninterpreted source code file.
For more information about "chkproc.c" see the
Fossies "Dox" file reference documentation and the latest
Fossies "Diffs" side-by-side code changes report:
0.54_vs_0.55.
1 /*
2 (C) Nelson Murilo - 2004/09/13
3 Version 0.10
4 C port from chkproc.pl code from Klaus Steding-Jessen <jessen@nic.br>
5 and Cristine Hoepers <cristine@nic.br> +little output changes.
6
7 2002/03/02 - Segmentation fault in ps for non ASCII user name, by RainbowHat
8
9 2002/06/13 Updated by Kostya Kortchinsky <kostya.kortchinsky@renater.fr>
10 - corrected the program return value ;
11 - added a verbose mode displaying information about the hidden process.
12
13 2002/08/08 - Value of MAX_PROCESSES was increased to 99999 (new versions
14 of FreeBSD, HP-UX and others), reported by Morohoshi Akihiko, Paul
15 and others.
16
17 2002/09/03 - Eliminate (?) false-positives. Original idea from Aaron Sherman.
18
19 2002/11/15 - Updated by Kostya Kortchinsky <kostya.kortchinsky@renater.fr>
20 - ported to SunOS.
21
22 2003/01/19 - Another Adore based lkm test. Original idea from Junichi Murakami
23
24 2003/02/02 - More little fixes - Nelson Murilo
25
26 2003/02/23 - Use of kill to eliminate false-positives abandonated, It is
27 preferable false-positives that false-negatives. Uncomment kill() functions
28 if you like it.
29
30 2003/06/07 - Fix for NPTL threading mechanisms - patch by Mike Griego
31
32 2003/09/01 - Fix for ps mode detect, patch by Bill Dupree and others
33
34 2004/04/03 - More fix for linux's threads - Nelson Murilo
35
36 2004/09/13 - More and more fix for linux's threads - Nelson Murilo
37
38 2005/02/23 - More and more and more fix for linux's threads - Nelson Murilo
39
40 2005/10/28 - Bug fix for FreeBSD: chkproc was sending a SIGXFSZ (kill -25)
41 to init, causing a reboot. Patch by Nelson Murilo.
42 Thanks to Luiz E. R. Cordeiro.
43
44 2005/11/15 - Add check for Enye LKM - Nelson Murilo
45
46 2005/11/25 - Fix for long lines in PS output - patch by Lantz Moore
47
48 2006/01/05 - Add getpriority to identify LKMs, ideas from Yjesus(unhide) and
49 Slider/Flimbo (skdet)
50
51 2006/01/11 - Fix signal 25 on parisc linux and return of kill() -
52 Thanks to Lantz Moore
53
54 2014/07/16 - MAX_PROCESSES now is 999999 -
55 Thanks to Nico Koenrades
56
57 2017/04/13 - MAX_PROCESSES now is 4194384 if linux64
58 Thanks to DS Store
59 */
60
61 #if !defined(__linux__) && !defined(__FreeBSD__) && !defined(__sun)
62 int main (){ return 0; }
63 #else
64 #include <stdio.h>
65 #include <string.h>
66 #include <errno.h>
67 #include <sys/types.h>
68 #include <dirent.h>
69 #include <ctype.h>
70 #include <stdlib.h>
71 #include <unistd.h>
72 #include <signal.h>
73 #include <sys/stat.h>
74 #if defined(__sun)
75 #include <procfs.h>
76 #include <fcntl.h>
77 #endif
78 #include <sys/resource.h>
79
80 #define PS_SUN 0
81 #define PS_LOL 1
82 #define PS_COM 2
83 #define PS_LNX 3
84 #define PS_MAX 3
85 #define ENYELKM "/proc/12345"
86 // #define ENYELKM "/tmp/12345"
87
88 #if defined(__sun)
89 #define FIRST_PROCESS 0
90 #else
91 #define FIRST_PROCESS 1
92 #endif
93 #define MAX_PROCESSES 999999
94 #if (defined (__x86_64) > 0 || defined (__amd64) > 0)
95 #undef MAX_PROCESSES
96 #define MAX_PROCESSES 4194304
97 #endif
98 #define MAX_BUF 1024
99
100 #if !defined (SIGXFSZ)
101 #define SIGXFSZ 25
102 #endif
103
104 static char *ps_cmds[] = {
105 "ps -edf",
106 "ps auxw",
107 "ps mauxw 2>&1 ",
108 "ps auxw -T|tr -s ' '|cut -d' ' -f2-",
109 };
110
111 int psproc [MAX_PROCESSES+1];
112 int dirproc[MAX_PROCESSES+1];
113 #if defined(__linux__)
114 int isathread[MAX_PROCESSES+1];
115 #endif
116
117 /*
118 * read at most the first (size-1) chars into s and terminate with a '\0'.
119 * stops reading after a newline or EOF. if a newline is read, it will be
120 * the last char in the string. if no newline is found in the first
121 * (size-1) chars, then keep reading and discarding chars until a newline
122 * is found or EOF.
123 */
124 char *readline(char *s, int size, FILE *stream)
125 {
126 char *rv = fgets(s, size, stream);
127
128 if (strlen(s) == (size-1) && s[size-1] != '\n')
129 {
130 char buf[MAX_BUF];
131 fgets(buf, MAX_BUF, stream);
132 while (strlen(buf) == (MAX_BUF-1) && buf[MAX_BUF-1] != '\n')
133 {
134 fgets(buf, MAX_BUF, stream);
135 }
136 }
137
138 return rv;
139 }
140
141 int main(int argc, char **argv)
142 {
143 char buf[MAX_BUF], *p, path[MAX_BUF];
144 char *pscmd = (char *)0;
145 FILE *ps;
146 DIR *proc = opendir("/proc");
147 struct dirent *dir;
148 struct stat sb;
149 int i, j, retps, retdir, pv, verbose;
150 long ret = 0L;
151 char * tmp_d_name;
152 #if defined(__linux__)
153 int maybeathread;
154 #endif
155 #if defined(__sun)
156 psinfo_t psbuf;
157 #endif
158
159 pv = verbose = 0;
160
161 if (!proc)
162 {
163 perror("proc");
164 exit (1);
165 }
166 for (i = 1; i < argc; i++)
167 {
168 if (!memcmp(argv[i], "-v", 2))
169 verbose++;
170 else if (!memcmp(argv[i], "-?", 2))
171 {
172 printf("Usage: %s [-v] [-v] -p <num>\n", argv[0]);
173 return 0;
174 }
175 #if defined(__linux__)
176 else if (!memcmp(argv[i], "-p", 2))
177 {
178 if (i+1 < argc)
179 pv = atoi(argv[++i]);
180 else
181 {
182 printf("Usage: %s [-v] [-v] [-p procps version]\n", argv[0]);
183 return 0;
184 }
185 }
186 #endif
187 }
188 #if defined(__sun)
189 pscmd = ps_cmds[PS_SUN];
190 #elif !defined (__linux__)
191 pscmd = ps_cmds[PS_COM];
192 #endif
193 #if defined(__linux__)
194 if (pv < 1 || pv > PS_MAX)
195 pv = 1;
196 pscmd = ps_cmds[pv];
197 /* printf("pv = %d\n\r", pv); /* -- DEBUG */
198 #endif
199
200 /* printf("pscmd = %s\n\r", pscmd); /* -- DEBUG */
201 if (!(ps = popen(pscmd, "r")))
202 {
203 perror("ps");
204 exit(errno);
205 }
206
207 *buf = 0;
208 readline(buf, MAX_BUF, ps); /* Skip header */
209 #if defined(__sun)
210 if (!isspace(*buf))
211 #else
212 if (!isalpha(*buf))
213 #endif
214 {
215 readline(buf, MAX_BUF, ps); /* Skip header */
216 if (!isalpha(*buf) && pv != PS_LNX)
217 {
218 if (pv != PS_LOL)
219 execlp(argv[0], argv[0], "-p 1", NULL);
220 fprintf(stderr, "OooPS!\n");
221 exit(2);
222 }
223 }
224 if (!memcmp(buf, "ps:", 3) && (pv != PS_LOL))
225 execlp(argv[0], argv[0], "-p 1", NULL);
226
227 for (i = FIRST_PROCESS; i <= MAX_PROCESSES; i++) { /* Init matrix */
228 psproc[i] = dirproc[i] = 0;
229 #if defined(__linux__)
230 isathread[i] = 0;
231 #endif
232 }
233
234 while (readline(buf, MAX_BUF, ps))
235 {
236 p = buf;
237 #if defined(__sun)
238 while (isspace(*p)) /* Skip spaces */
239 p++;
240 #endif
241 while (!isspace(*p)) /* Skip User */
242 p++;
243 while (isspace(*p)) /* Skip spaces */
244 p++;
245 /* printf(">>PS %s<<\n", p); /* -- DEBUG */
246 ret = atol(p);
247 if ( ret < 0 || ret > MAX_PROCESSES )
248 {
249 fprintf (stderr, " OooPS, not expected %ld value\n", ret);
250 exit (2);
251 }
252 psproc[ret] = 1;
253 }
254 pclose(ps);
255
256 while ((dir = readdir(proc)))
257 {
258 #if defined(__linux__)
259 maybeathread = 0;
260 #endif
261 tmp_d_name = dir->d_name;
262 if (!strcmp(tmp_d_name, ".") || !strcmp(tmp_d_name, ".."))
263 continue;
264 #if defined(__linux__)
265 if (*tmp_d_name == '.') { /* here we catch the new NTPL threads in linux. They are listed in /proc as PIDs with a period prepended */
266 tmp_d_name++;
267 maybeathread = 1;
268 }
269 #endif
270 if(!isdigit(*tmp_d_name))
271 continue;
272 #if defined(__linux__)
273 else if (maybeathread) {
274 isathread[atol(tmp_d_name)] = 1; /* mark it as a linux NTPL thread if it's in the form of "\.[0-9]*" */
275 if (verbose)
276 printf("%ld is a Linux Thread, marking as such...\n", atol(tmp_d_name));
277 }
278 #endif
279
280 /* printf("%s\n", tmp_d_name); /* -- DEBUG */
281 dirproc[atol(tmp_d_name)] = 1;
282 }
283 closedir(proc);
284
285 /* Brute force */
286 strcpy(buf, "/proc/");
287 retps = retdir = 0;
288 for (i = FIRST_PROCESS; i <= MAX_PROCESSES; i++)
289 {
290 // snprintf(&buf[6], 6, "%d", i);
291 snprintf(&buf[6], 8, "%d", i);
292 if (!chdir(buf))
293 {
294 if (!dirproc[i] && !psproc[i])
295 {
296 #if defined(__linux__)
297 if (!isathread[i]) {
298 #endif
299 retdir++;
300 if (verbose)
301 printf ("PID %5d(%s): not in readdir output\n", i, buf);
302 #if defined(__linux__)
303 }
304 #endif
305 }
306 if (!psproc[i] ) /* && !kill(i, 0)) */
307 {
308 #if defined(__linux__)
309 if(!isathread[i]) {
310 #endif
311 retps++;
312 if (verbose)
313 printf ("PID %5d: not in ps output\n", i);
314 #if defined(__linux__)
315 }
316 #endif
317 }
318 #if defined(__linux__)
319 if(!isathread[i]) {
320 #endif
321 /* if ((!dirproc[i] || !psproc[i]) && !kill(i, 0) && (verbose > 1)) */
322 if ((!dirproc[i] || !psproc[i]) && (verbose > 1))
323 {
324 #if defined(__linux__)
325 j = readlink ("./cwd", path, sizeof(path));
326 path[(j < sizeof(path)) ? j : sizeof(path) - 1] = 0;
327 printf ("CWD %5d: %s\n", i, path);
328 j = readlink ("./exe", path, sizeof(path));
329 path[(j < sizeof(path)) ? j : sizeof(path) - 1] = 0;
330 printf ("EXE %5d: %s\n", i, path);
331 #elif defined(__FreeBSD__)
332 j = readlink ("./file", path, sizeof(path));
333 path[(j < sizeof(path)) ? j : sizeof(path) - 1] = 0;
334 printf ("FILE %5d: %s\n", i, path);
335 #elif defined(__sun)
336 if ((j = open("./psinfo", O_RDONLY)) != -1)
337 {
338 if (read(j, &psbuf, sizeof(psbuf)) == sizeof(psbuf))
339 printf ("PSINFO %5d: %s\n", i, psbuf.pr_psargs);
340 else
341 printf ("PSINFO %5d: unknown\n", i);
342 close(j);
343 }
344 else
345 printf ("PSINFO %5d: unknown\n", i);
346 #endif
347 }
348 #if defined(__linux__)
349 }
350 #endif
351 }
352 #ifndef __FreeBSD__
353 else
354 {
355 errno = 0;
356 getpriority(PRIO_PROCESS, i);
357 if (!errno)
358 {
359 retdir++;
360 if (verbose)
361 printf ("PID %5d(%s): not in getpriority readdir output\n", i, buf);
362 }
363 }
364 #endif
365 }
366 if (retdir)
367 printf("You have % 5d process hidden for readdir command\n", retdir);
368 if (retps)
369 printf("You have % 5d process hidden for ps command\n", retps);
370 #if defined(__linux__)
371 kill(1, 100); /* Check for SIGINVISIBLE Adore signal */
372 if (kill (1, SIGXFSZ) < 0 && errno == 3)
373 {
374 printf("SIGINVISIBLE Adore found\n");
375 retdir+= errno;
376 }
377 /* Check for Enye LKM */
378 if (stat(ENYELKM, &sb) && kill (12345, 58) >= 0)
379 {
380 printf("Enye LKM found\n");
381 retdir+= errno;
382 }
383 #endif
384 return (retdir+retps);
385 }
386 #endif