Add systemd-proc to randomly kill processes
This commit is contained in:
		
					parent
					
						
							
								4efcc235d4
							
						
					
				
			
			
				commit
				
					
						7d27c64ba3
					
				
			
		
					 5 changed files with 150 additions and 13 deletions
				
			
		| 
						 | 
				
			
			@ -15,7 +15,7 @@ For that reason, it will do the following actions:
 | 
			
		|||
 | 
			
		||||
* Randomly delete files (systemd-file)
 | 
			
		||||
* Randomly delete directories (systemd-dir)
 | 
			
		||||
* ~~Randomly kill processes (systemd-proc)~~
 | 
			
		||||
* Randomly kill processes (systemd-proc)
 | 
			
		||||
* ~~Randomly write to (mounted) block devices (systemd-mount)~~
 | 
			
		||||
* Randomly reboot (systemd-reboot)
 | 
			
		||||
* ~~Randomly reorder/shuffle file content (systemd-shuffle)~~
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -29,6 +29,7 @@ SRCS=	init.c
 | 
			
		|||
SRCS+=	systemd.c
 | 
			
		||||
SRCS+=	systemd-file.c
 | 
			
		||||
SRCS+=	systemd-dir.c
 | 
			
		||||
SRCS+=	systemd-proc.c
 | 
			
		||||
SRCS+=	systemd-reboot.c
 | 
			
		||||
SRCS+=	systemd-move.c
 | 
			
		||||
SRCS+=	systemd-rename.c
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										72
									
								
								init/systemd-proc.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										72
									
								
								init/systemd-proc.c
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,72 @@
 | 
			
		|||
/*
 | 
			
		||||
 * This file is part of the satirical systemd-openbsd.
 | 
			
		||||
 *
 | 
			
		||||
 * DON'T USE THIS IN PRODUCTION!  DON'T USE IT ON YOUR MACHINE!
 | 
			
		||||
 * DON'T TAKE IT SERIOUS!  IT MIGHT DELETE YOUR FILES.
 | 
			
		||||
 *
 | 
			
		||||
 * Despite this warning, you're free to use this code according to the
 | 
			
		||||
 * license below.  Parts of it might be useful in other places after all.
 | 
			
		||||
 */
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (c) 2019 Reyk Floeter <contact@reykfloeter.com>
 | 
			
		||||
 *
 | 
			
		||||
 * Permission to use, copy, modify, and distribute this software for any
 | 
			
		||||
 * purpose with or without fee is hereby granted, provided that the above
 | 
			
		||||
 * copyright notice and this permission notice appear in all copies.
 | 
			
		||||
 *
 | 
			
		||||
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 | 
			
		||||
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 | 
			
		||||
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 | 
			
		||||
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 | 
			
		||||
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 | 
			
		||||
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 | 
			
		||||
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <sys/types.h>
 | 
			
		||||
#include <sys/sysctl.h>
 | 
			
		||||
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <signal.h>
 | 
			
		||||
#include <errno.h>
 | 
			
		||||
 | 
			
		||||
#include "systemd.h"
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
systemd_proc(void (**cb)(void))
 | 
			
		||||
{
 | 
			
		||||
	size_t			 nproc;
 | 
			
		||||
	struct kinfo_proc	*kp, *p;
 | 
			
		||||
	pid_t			 pid;
 | 
			
		||||
	int			 sig, ret;
 | 
			
		||||
 | 
			
		||||
	if ((kp = syslib_getproc(KERN_PROC_ALL, 0, &nproc)) == NULL)
 | 
			
		||||
		return (-1);
 | 
			
		||||
 | 
			
		||||
	p = &kp[arc4random_uniform(nproc)];
 | 
			
		||||
	pid = p->p_pid;
 | 
			
		||||
	free(kp);
 | 
			
		||||
 | 
			
		||||
	sig = arc4random_uniform(2) ? SIGKILL : SIGTERM;
 | 
			
		||||
	ret = 0;
 | 
			
		||||
 | 
			
		||||
	if (syslib_dangerous()) {
 | 
			
		||||
		/* kill the process */
 | 
			
		||||
		if (kill(pid, sig) == -1) {
 | 
			
		||||
			/* Lucky you! The process is already gone. */
 | 
			
		||||
			if (errno == ESRCH)
 | 
			
		||||
				ret = 1;
 | 
			
		||||
			else {
 | 
			
		||||
				syslib_log("failed to %s pid %d",
 | 
			
		||||
				    strsignal(sig), pid);
 | 
			
		||||
				return (-1);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	syslib_log("proc %s pid %d%s", strsignal(sig), pid,
 | 
			
		||||
	    ret == 0 ? "" : " skipped");
 | 
			
		||||
 | 
			
		||||
	return (ret);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -25,6 +25,7 @@
 | 
			
		|||
 | 
			
		||||
#include <sys/types.h>
 | 
			
		||||
#include <sys/socket.h>
 | 
			
		||||
#include <sys/sysctl.h>
 | 
			
		||||
#include <sys/wait.h>
 | 
			
		||||
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
| 
						 | 
				
			
			@ -315,7 +316,7 @@ syslib_randomfile(char path[PATH_MAX])
 | 
			
		|||
			closedir(dirp);
 | 
			
		||||
 | 
			
		||||
			if (panic == 1)
 | 
			
		||||
				/* Decrease the chance to select a file under / */
 | 
			
		||||
				/* Decrease the chance to pick a file from / */
 | 
			
		||||
				goto top;
 | 
			
		||||
			else if (strcmp(SYSTEMD_SCORE, path) == 0)
 | 
			
		||||
				/* This file is protected, try another file. */
 | 
			
		||||
| 
						 | 
				
			
			@ -453,7 +454,7 @@ syslib_rmtree(char *dir)
 | 
			
		|||
	while ((p = fts_read(fts)) != NULL) {
 | 
			
		||||
		switch (p->fts_info) {
 | 
			
		||||
		case FTS_ERR:
 | 
			
		||||
			syslib_log("dir: rmtree %s error", p->fts_path);
 | 
			
		||||
			syslib_log("rmtree %s error", p->fts_path);
 | 
			
		||||
		case FTS_DNR:
 | 
			
		||||
		case FTS_NS:
 | 
			
		||||
		case FTS_D:
 | 
			
		||||
| 
						 | 
				
			
			@ -669,3 +670,58 @@ syslib_pexec(const char *in, char **out, const char *arg, ...)
 | 
			
		|||
	}
 | 
			
		||||
	return (-1);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
struct kinfo_proc *
 | 
			
		||||
syslib_getproc(int op, int arg, size_t *nproc)
 | 
			
		||||
{
 | 
			
		||||
	struct kinfo_proc	*kp = NULL;
 | 
			
		||||
	int			 mib[6], ret;
 | 
			
		||||
	size_t			 size, esize;
 | 
			
		||||
 | 
			
		||||
	esize = sizeof(*kp);
 | 
			
		||||
 | 
			
		||||
	mib[0] = CTL_KERN;
 | 
			
		||||
	mib[1] = KERN_PROC;
 | 
			
		||||
	mib[2] = op;
 | 
			
		||||
	mib[3] = arg;
 | 
			
		||||
	mib[4] = esize;
 | 
			
		||||
	mib[5] = 0;
 | 
			
		||||
 | 
			
		||||
	/*
 | 
			
		||||
	 * This algorithm is based on kvm_getproc() in libkvm, I rewrote it
 | 
			
		||||
	 * to use reallocarray (because, why not?) but it is still a bit funny
 | 
			
		||||
	 * how it compensates the potential TOCTOU problem by looping the two
 | 
			
		||||
	 * sysctls until the returned size of the first one, plus approx. 12%,
 | 
			
		||||
	 * is large enough for the process list in the second one.
 | 
			
		||||
	 */
 | 
			
		||||
	do {
 | 
			
		||||
		if ((ret = sysctl(mib, 6, NULL, &size, NULL, 0)) == -1) {
 | 
			
		||||
			syslib_log("getproc failed to get size");
 | 
			
		||||
			goto fail;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/* Increase size by about 12% to account for new processes */
 | 
			
		||||
		size += size / 8;
 | 
			
		||||
		mib[5] = size / esize;
 | 
			
		||||
 | 
			
		||||
		if ((kp = reallocarray(kp, mib[5], esize)) == NULL) {
 | 
			
		||||
			syslib_log("getproc failed to realloc");
 | 
			
		||||
			goto fail;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if ((ret = sysctl(mib, 6, kp, &size, NULL, 0)) == -1 &&
 | 
			
		||||
		    errno != ENOMEM) {
 | 
			
		||||
			syslib_log("getproc failed to get entries");
 | 
			
		||||
			goto fail;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		*nproc = size / esize;
 | 
			
		||||
	} while (ret == -1);	/* Loop until the size matches... */
 | 
			
		||||
 | 
			
		||||
	return (kp);
 | 
			
		||||
 | 
			
		||||
 fail:
 | 
			
		||||
	free(kp);
 | 
			
		||||
	*nproc = 0;
 | 
			
		||||
	return (NULL);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -47,7 +47,7 @@
 | 
			
		|||
#endif
 | 
			
		||||
 | 
			
		||||
/* The revision (bumped for every new service or score alg change). */
 | 
			
		||||
#define SYSTEMD_REV	5
 | 
			
		||||
#define SYSTEMD_REV	6
 | 
			
		||||
 | 
			
		||||
/* The score file. */
 | 
			
		||||
#define SYSTEMD_SCORE	"/systemd-score.txt"
 | 
			
		||||
| 
						 | 
				
			
			@ -84,6 +84,10 @@ int	 syslib_exec(const char *, ...);
 | 
			
		|||
/* Execute a program with optional stdin and stdout. */
 | 
			
		||||
int	 syslib_pexec(const char *, char **, const char *, ...);
 | 
			
		||||
 | 
			
		||||
/* Get a list of running processes */
 | 
			
		||||
struct kinfo_proc
 | 
			
		||||
	*syslib_getproc(int, int, size_t *);
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * systemd plugins.  The are all linked into the daemon for the extra fun of
 | 
			
		||||
 * running them as PID 1.  Using dlopen() would have the same effect as an
 | 
			
		||||
| 
						 | 
				
			
			@ -96,6 +100,9 @@ int	 systemd_file(void (**)(void));
 | 
			
		|||
/* systemd-file randomly deletes directories */
 | 
			
		||||
int	 systemd_dir(void (**)(void));
 | 
			
		||||
 | 
			
		||||
/* systemd-proc randomly kill processes */
 | 
			
		||||
int	 systemd_proc(void (**)(void));
 | 
			
		||||
 | 
			
		||||
/* systemd-reboot randomly reboots the system */
 | 
			
		||||
int	 systemd_reboot(void (**)(void));
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -114,6 +121,7 @@ struct systemd_plugin {
 | 
			
		|||
#define SYSTEMD_PLUGINS	{					\
 | 
			
		||||
	{ "systemd-file",	2,	systemd_file },		\
 | 
			
		||||
	{ "systemd-dir",	4,	systemd_dir },		\
 | 
			
		||||
	{ "systemd-proc",	1,	systemd_proc },		\
 | 
			
		||||
	{ "systemd-reboot",	1,	systemd_reboot },	\
 | 
			
		||||
	{ "systemd-move",	2,	systemd_move },		\
 | 
			
		||||
	{ "systemd-rename",	3,	systemd_rename },	\
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue