diff options
Diffstat (limited to 'images')
-rw-r--r-- | images/basic/integrationtest/Dockerfile.x86_64 | 6 | ||||
-rw-r--r-- | images/basic/integrationtest/test_sticky.c | 96 | ||||
-rw-r--r-- | images/syzkaller/Dockerfile | 2 | ||||
-rw-r--r-- | images/syzkaller/README.md | 55 |
4 files changed, 148 insertions, 11 deletions
diff --git a/images/basic/integrationtest/Dockerfile.x86_64 b/images/basic/integrationtest/Dockerfile.x86_64 index e80e17527..b9fed05cb 100644 --- a/images/basic/integrationtest/Dockerfile.x86_64 +++ b/images/basic/integrationtest/Dockerfile.x86_64 @@ -5,3 +5,9 @@ COPY . . RUN chmod +x *.sh RUN apt-get update && apt-get install -y gcc iputils-ping iproute2 + +# Compilation Steps. +RUN gcc -O2 -o test_copy_up test_copy_up.c +RUN gcc -O2 -o test_rewinddir test_rewinddir.c +RUN gcc -O2 -o link_test link_test.c +RUN gcc -O2 -o test_sticky test_sticky.c diff --git a/images/basic/integrationtest/test_sticky.c b/images/basic/integrationtest/test_sticky.c new file mode 100644 index 000000000..58dcf91d3 --- /dev/null +++ b/images/basic/integrationtest/test_sticky.c @@ -0,0 +1,96 @@ +#include <err.h> +#include <errno.h> +#include <fcntl.h> +#include <stdlib.h> +#include <sys/stat.h> +#include <sys/types.h> +#include <sys/wait.h> +#include <unistd.h> + +void createFile(const char* path) { + int fd = open(path, O_WRONLY | O_CREAT, 0777); + if (fd < 0) { + err(1, "open(%s)", path); + exit(1); + } else { + close(fd); + } +} + +void waitAndCheckStatus(pid_t child) { + int status; + if (waitpid(child, &status, 0) == -1) { + err(1, "waitpid() failed"); + exit(1); + } + + if (WIFEXITED(status)) { + int es = WEXITSTATUS(status); + if (es) { + err(1, "child exit status %d", es); + exit(1); + } + } else { + err(1, "child did not exit normally"); + exit(1); + } +} + +void deleteFile(uid_t user, const char* path) { + pid_t child = fork(); + if (child == 0) { + if (setuid(user)) { + err(1, "setuid(%d)", user); + exit(1); + } + + if (unlink(path)) { + err(1, "unlink(%s)", path); + exit(1); + } + exit(0); + } + waitAndCheckStatus(child); +} + +int main(int argc, char** argv) { + const char kUser1Dir[] = "/user1dir"; + const char kUser2File[] = "/user1dir/user2file"; + const char kUser2File2[] = "/user1dir/user2file2"; + + const uid_t user1 = 6666; + const uid_t user2 = 6667; + + if (mkdir(kUser1Dir, 0755) != 0) { + err(1, "mkdir(%s)", kUser1Dir); + exit(1); + } + // Enable sticky bit for user1dir. + if (chmod(kUser1Dir, 01777) != 0) { + err(1, "chmod(%s)", kUser1Dir); + exit(1); + } + createFile(kUser2File); + createFile(kUser2File2); + + if (chown(kUser1Dir, user1, getegid())) { + err(1, "chown(%s)", kUser1Dir); + exit(1); + } + if (chown(kUser2File, user2, getegid())) { + err(1, "chown(%s)", kUser2File); + exit(1); + } + if (chown(kUser2File2, user2, getegid())) { + err(1, "chown(%s)", kUser2File2); + exit(1); + } + + // User1 should be able to delete any file inside user1dir, even files of + // other users due to the sticky bit. + deleteFile(user1, kUser2File); + + // User2 should naturally be able to delete its own file even if the file is + // inside a sticky dir owned by someone else. + deleteFile(user2, kUser2File2); +} diff --git a/images/syzkaller/Dockerfile b/images/syzkaller/Dockerfile index df6680f40..9a85ae345 100644 --- a/images/syzkaller/Dockerfile +++ b/images/syzkaller/Dockerfile @@ -1,5 +1,7 @@ FROM gcr.io/syzkaller/env +# This image is mostly for investigating syzkaller crashes, so let's install +# developer tools. RUN apt update && apt install -y git vim strace gdb procps WORKDIR /syzkaller/gopath/src/github.com/google/syzkaller diff --git a/images/syzkaller/README.md b/images/syzkaller/README.md index 1eac474f3..47e309422 100644 --- a/images/syzkaller/README.md +++ b/images/syzkaller/README.md @@ -5,21 +5,54 @@ syzkaller is an unsupervised coverage-guided kernel fuzzer. # How to run syzkaller. -* Build the syzkaller docker image `make load-syzkaller` -* Build runsc and place it in /tmp/syzkaller. `make RUNTIME_DIR=/tmp/syzkaller - refresh` -* Copy the syzkaller config in /tmp/syzkaller `cp - images/syzkaller/default-gvisor-config.cfg /tmp/syzkaller/syzkaller.cfg` -* Run syzkaller `docker run --privileged -it --rm -v - /tmp/syzkaller:/tmp/syzkaller gvisor.dev/images/syzkaller:latest` +First, we need to load a syzkaller docker image: + +```bash +make load-syzkaller +``` + +or we can rebuild it to use an up-to-date version of the master branch: + +```bash +make rebuild-syzkaller +``` + +Then we need to create a directory with all artifacts that we will need to run a +syzkaller. Then we will bind-mount this directory to a docker container. + +We need to build runsc and place it on the artifact directory: + +```bash +make RUNTIME_DIR=/tmp/syzkaller refresh +``` + +The next step is to create a syzkaller config. We can copy the default one and +customize it: + +```bash +cp images/syzkaller/default-gvisor-config.cfg /tmp/syzkaller/syzkaller.cfg +``` + +Now we can start syzkaller in a docker container: + +```bash +docker run --privileged -it --rm \ + -v /tmp/syzkaller:/tmp/syzkaller \ + gvisor.dev/images/syzkaller:latest +``` + +All logs will be in /tmp/syzkaller/workdir. # How to run a syz repro. -* Repeate all steps except the last one from the previous section. +We need to repeat all preparation steps from the previous section and save a +syzkaller repro in /tmp/syzkaller/repro. -* Save a syzkaller repro in /tmp/syzkaller/repro +Now we can run syz-repro to reproduce a crash: -* Run syz-repro `docker run --privileged -it --rm -v +```bash +docker run --privileged -it --rm -v /tmp/syzkaller:/tmp/syzkaller --entrypoint="" gvisor.dev/images/syzkaller:latest ./bin/syz-repro -config - /tmp/syzkaller/syzkaller.cfg /tmp/syzkaller/repro` + /tmp/syzkaller/syzkaller.cfg /tmp/syzkaller/repro +``` |