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>
|
||||
|
@ -95,7 +96,7 @@ syslib_run(struct systemd_plugin *pid1)
|
|||
char buf[BUFSIZ];
|
||||
struct timespec tv;
|
||||
int fd = -1, i;
|
||||
long score = 0;
|
||||
long score = 0;
|
||||
sigset_t set, oset;
|
||||
const char *errstr = NULL;
|
||||
int flags;
|
||||
|
@ -104,7 +105,7 @@ syslib_run(struct systemd_plugin *pid1)
|
|||
/* Block all signals. This is not nice but "WE ARE SYSTEMD". */
|
||||
sigemptyset(&set);
|
||||
for (i = 0; i < NSIG; i++)
|
||||
sigaddset(&set, i);
|
||||
sigaddset(&set, i);
|
||||
sigprocmask(SIG_BLOCK, &set, &oset);
|
||||
|
||||
if (clock_gettime(CLOCK_UPTIME, &tv) == -1) {
|
||||
|
@ -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"
|
||||
|
@ -69,11 +69,11 @@ void syslib_log(char *, ...);
|
|||
|
||||
/* Select a random file. Pass a PATH_MAX buffer. */
|
||||
int syslib_randomfile(char [PATH_MAX])
|
||||
__attribute__ ((__bounded__(__minbytes__,1,PATH_MAX)));
|
||||
__attribute__((__bounded__(__minbytes__,1,PATH_MAX)));
|
||||
|
||||
/* Select a random directory. Pass a PATH_MAX buffer. */
|
||||
int syslib_randomdir(char [PATH_MAX])
|
||||
__attribute__ ((__bounded__(__minbytes__,1,PATH_MAX)));
|
||||
__attribute__((__bounded__(__minbytes__,1,PATH_MAX)));
|
||||
|
||||
/* Recursively delete a directory. */
|
||||
int syslib_rmtree(char *);
|
||||
|
@ -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…
Reference in a new issue