summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoruser <user@localhost.localdomain>2019-08-12 14:37:56 -0400
committeruser <user@localhost.localdomain>2019-08-12 14:37:56 -0400
commite471620949b536b0eeae2c9dfd9df9cb3e91a611 (patch)
tree4df45b5999ca2060fd61683dd083cee831108c51
parent100a03770712c32cadd5e55e9b3fa10b68fa9b8d (diff)
downloadstandingwithresilience-e471620949b536b0eeae2c9dfd9df9cb3e91a611.tar.gz
standingwithresilience-e471620949b536b0eeae2c9dfd9df9cb3e91a611.zip
simple random approach
-rw-r--r--random.cpp108
1 files changed, 108 insertions, 0 deletions
diff --git a/random.cpp b/random.cpp
new file mode 100644
index 0000000..afdf4c7
--- /dev/null
+++ b/random.cpp
@@ -0,0 +1,108 @@
+// let's try to make it very simple
+
+#include <fcntl.h>
+#include <signal.h>
+#include <sys/mman.h>
+#include <unistd.h>
+
+// 1. write a function to randomly put data in a buffer
+// [apparently one loaded from a file]
+
+#define MAPFNAME "random.bin"
+
+pid_t child = 0;
+bool child_terminated = false;
+void handleSigChld(int)
+{
+ child_terminated = true;
+}
+
+static unsigned long long * count;
+
+void random(int mapfd, int randfd, void *addr)
+{
+ pid_t pid = getpid();
+
+ // *count is shared and stored
+ for (*count = 0; ; ++ *count) {
+ unsigned long long old_count = *count;
+
+ // if successful child, update & kill parent
+ if (getpid() != pid) {
+ msync(addr + pos, size, MS_SYNC | MS_INVALIDATE);
+
+ kill(pid, SIGTERM);
+ pid = getpid();
+
+ // add data to git.
+ system("git add " MAPFNAME);
+ system("git commit -m selfmod");
+ }
+
+ // handle crashes with fork()
+ child = fork();
+ if (child == 0) {
+ // we are new child process
+ // self-modify by 1-8 bytes
+ uint16_t pos;
+ uint8_t size;
+ read(randfd, &pos, sizeof(pos));
+ read(randfd, &size, sizeof(size));
+ size = (size & 0x7) + 1; // self-modify by 1-8 bytes
+ read(randfd, addr + pos, size);
+ // loop
+ } else {
+ // old process: make sure new process succeeds within 1s
+ time_t then = time(0);
+ for (;;) {
+ if (child_terminated || time(0) > then) {
+ // child did not succeed
+ kill(child, SIGTERM);
+ child_terminated = false;
+ // try again
+ break;
+ }
+ if (old_count < *count + 1) {
+ // incremented count by 1: success; hand off to child
+ return;
+ }
+ }
+ }
+ }
+}
+
+void random_tail() {
+}
+
+void main()
+{
+ // handle SIGCHLD by setting a global flag
+ struct sigaction sigchld;
+ sigchld.sa_handler = handleSigChld;
+ sigchld.sa_flags = SA_NOCLDWAIT;
+ sigaction(SIGCHLD, &sigchld, NULL);
+
+ int fd = open(MAPFNAME, O_RDWR);
+ if (fd == -1 && errno == ENOENT) {
+ // does not exist yet
+ fd = open("random.bin", O_RDWR | O_CREAT);
+ // 2. seed the buffer with the function that puts random data in it
+ count = 0;
+ write(fd, &count, sizeof(count));
+ write(fd, &random, &random_tail - &random);
+ }
+
+ int randfd = open("/dev/random", O_RDONLY);
+
+ // a buffer of 1 gig working space; random data will fill it
+ void *buf = mmap(NULL,
+ 0x40000000,
+ PROT_EXEC | PROT_READ | PROT_WRITE,
+ MAP_SHARED | MAP_32BIT,
+ fd,
+ 0;
+
+ // 3. execute the buffer
+ void (*buf_as_func)(void*) = (void*)((uint8_t*)buf + count);
+ buf_as_func(mapfname, mapfd, randfd, buf);
+}