0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013 #include <linux/filter.h>
0014 #include <linux/seccomp.h>
0015 #include <linux/unistd.h>
0016 #include <stdio.h>
0017 #include <string.h>
0018 #include <sys/prctl.h>
0019 #include <unistd.h>
0020
0021 #include "bpf-helper.h"
0022
0023 #ifndef PR_SET_NO_NEW_PRIVS
0024 #define PR_SET_NO_NEW_PRIVS 38
0025 #endif
0026
0027 int main(int argc, char **argv)
0028 {
0029 struct bpf_labels l = {
0030 .count = 0,
0031 };
0032 static const char msg1[] = "Please type something: ";
0033 static const char msg2[] = "You typed: ";
0034 char buf[256];
0035 struct sock_filter filter[] = {
0036
0037 LOAD_SYSCALL_NR,
0038 SYSCALL(__NR_exit, ALLOW),
0039 SYSCALL(__NR_exit_group, ALLOW),
0040 SYSCALL(__NR_write, JUMP(&l, write_fd)),
0041 SYSCALL(__NR_read, JUMP(&l, read)),
0042 DENY,
0043
0044 LABEL(&l, read),
0045 ARG(0),
0046 JNE(STDIN_FILENO, DENY),
0047 ARG(1),
0048 JNE((unsigned long)buf, DENY),
0049 ARG(2),
0050 JGE(sizeof(buf), DENY),
0051 ALLOW,
0052
0053 LABEL(&l, write_fd),
0054 ARG(0),
0055 JEQ(STDOUT_FILENO, JUMP(&l, write_buf)),
0056 JEQ(STDERR_FILENO, JUMP(&l, write_buf)),
0057 DENY,
0058
0059 LABEL(&l, write_buf),
0060 ARG(1),
0061 JEQ((unsigned long)msg1, JUMP(&l, msg1_len)),
0062 JEQ((unsigned long)msg2, JUMP(&l, msg2_len)),
0063 JEQ((unsigned long)buf, JUMP(&l, buf_len)),
0064 DENY,
0065
0066 LABEL(&l, msg1_len),
0067 ARG(2),
0068 JLT(sizeof(msg1), ALLOW),
0069 DENY,
0070
0071 LABEL(&l, msg2_len),
0072 ARG(2),
0073 JLT(sizeof(msg2), ALLOW),
0074 DENY,
0075
0076 LABEL(&l, buf_len),
0077 ARG(2),
0078 JLT(sizeof(buf), ALLOW),
0079 DENY,
0080 };
0081 struct sock_fprog prog = {
0082 .filter = filter,
0083 .len = (unsigned short)(sizeof(filter)/sizeof(filter[0])),
0084 };
0085 ssize_t bytes;
0086 bpf_resolve_jumps(&l, filter, sizeof(filter)/sizeof(*filter));
0087
0088 if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0)) {
0089 perror("prctl(NO_NEW_PRIVS)");
0090 return 1;
0091 }
0092
0093 if (prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog)) {
0094 perror("prctl(SECCOMP)");
0095 return 1;
0096 }
0097 syscall(__NR_write, STDOUT_FILENO, msg1, strlen(msg1));
0098 bytes = syscall(__NR_read, STDIN_FILENO, buf, sizeof(buf)-1);
0099 bytes = (bytes > 0 ? bytes : 0);
0100 syscall(__NR_write, STDERR_FILENO, msg2, strlen(msg2));
0101 syscall(__NR_write, STDERR_FILENO, buf, bytes);
0102
0103 syscall(__NR_write, STDERR_FILENO, msg2, strlen(msg2)+2);
0104 return 0;
0105 }