make seccomp filter more pedantic (only allow O_APPEND on journal)
update seccomp filter to newest glibc (newfsstatat)
This commit is contained in:
48
tinyldap.c
48
tinyldap.c
@@ -39,6 +39,7 @@
|
|||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
#include <netinet/tcp.h>
|
#include <netinet/tcp.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
#if defined(STANDALONE) || defined(DEBUG)
|
#if defined(STANDALONE) || defined(DEBUG)
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
@@ -2395,6 +2396,7 @@ static void answerwithjournal(struct SearchRequest* sr,long messageid,int out) {
|
|||||||
# define SECCOMP_MODE_FILTER 2 /* uses user-supplied filter. */
|
# define SECCOMP_MODE_FILTER 2 /* uses user-supplied filter. */
|
||||||
# define SECCOMP_RET_KILL 0x00000000U /* kill the task immediately */
|
# define SECCOMP_RET_KILL 0x00000000U /* kill the task immediately */
|
||||||
# define SECCOMP_RET_TRAP 0x00030000U /* disallow and force a SIGSYS */
|
# define SECCOMP_RET_TRAP 0x00030000U /* disallow and force a SIGSYS */
|
||||||
|
# define SECCOMP_RET_ERRNO 0x00050000U /* returns an errno */
|
||||||
# define SECCOMP_RET_ALLOW 0x7fff0000U /* allow */
|
# define SECCOMP_RET_ALLOW 0x7fff0000U /* allow */
|
||||||
struct seccomp_data {
|
struct seccomp_data {
|
||||||
int nr;
|
int nr;
|
||||||
@@ -2463,36 +2465,46 @@ static int install_syscall_filter(void) {
|
|||||||
|
|
||||||
/* we need a special case for open.
|
/* we need a special case for open.
|
||||||
* we want open to succeed, but only if it's on the journal */
|
* we want open to succeed, but only if it's on the journal */
|
||||||
BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, __NR_open, 0, 8),
|
BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, __NR_open, 0, 10),
|
||||||
/* it's open(2). Load first argument into accumulator (first
|
/* it's open(2). Accept if mode == O_RDONLY or mode has O_APPEND */
|
||||||
* argument is filename, second is mode). */
|
/* load mode */
|
||||||
BPF_STMT(BPF_LD+BPF_W+BPF_ABS, offsetof(struct seccomp_data, args[0])),
|
|
||||||
/* make sure it is journalfilename */
|
|
||||||
BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, (uintptr_t)journalfilename, 0, 1),
|
|
||||||
/* "return SECCOMP_RET_ALLOW", tell seccomp to allow the syscall */
|
|
||||||
BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_ALLOW),
|
|
||||||
/* If we get here, it's not journalfilename. The only other file we allow is the data
|
|
||||||
* file, and that is only opened read-only. So check that mode is O_RDONLY */
|
|
||||||
BPF_STMT(BPF_LD+BPF_W+BPF_ABS, offsetof(struct seccomp_data, args[1])),
|
BPF_STMT(BPF_LD+BPF_W+BPF_ABS, offsetof(struct seccomp_data, args[1])),
|
||||||
/* mode & O_ACCMODE */
|
/* & O_ACCMODE */
|
||||||
BPF_STMT(BPF_ALU+BPF_AND+BPF_K, O_ACCMODE),
|
BPF_STMT(BPF_ALU+BPF_AND+BPF_K, O_ACCMODE),
|
||||||
/* if (mode & O_ACCMODE) == O_RDONLY goto ALLOW */
|
/* if (mode & O_ACCMODE) == O_RDONLY */
|
||||||
BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, O_RDONLY, 0, 1),
|
BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, O_RDONLY, 5, 0),
|
||||||
|
/* only let write access through with O_APPEND */
|
||||||
|
/* load mode again */
|
||||||
|
BPF_STMT(BPF_LD+BPF_W+BPF_ABS, offsetof(struct seccomp_data, args[1])),
|
||||||
|
/* & O_APPEND */
|
||||||
|
BPF_STMT(BPF_ALU+BPF_AND+BPF_K, O_APPEND),
|
||||||
|
/* if (mode & O_APPEND) == O_APPEND */
|
||||||
|
BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, O_APPEND, 0, 3),
|
||||||
|
/* load name */
|
||||||
|
BPF_STMT(BPF_LD+BPF_W+BPF_ABS, offsetof(struct seccomp_data, args[0])),
|
||||||
|
/* if (name == journalfilename) */
|
||||||
|
BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, (uintptr_t)journalfilename, 0, 1),
|
||||||
BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_ALLOW),
|
BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_ALLOW),
|
||||||
/* otherwise kill the process */
|
/* otherwise kill the process */
|
||||||
BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_KILL),
|
BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_KILL),
|
||||||
|
|
||||||
|
#ifdef __GLIBC__
|
||||||
/* glibc switched to openat instead of open */
|
/* glibc switched to openat instead of open */
|
||||||
BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, __NR_openat, 0, 8),
|
BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, __NR_openat, 0, 10),
|
||||||
|
BPF_STMT(BPF_LD+BPF_W+BPF_ABS, offsetof(struct seccomp_data, args[2])),
|
||||||
|
BPF_STMT(BPF_ALU+BPF_AND+BPF_K, O_ACCMODE),
|
||||||
|
BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, O_RDONLY, 5, 0),
|
||||||
|
BPF_STMT(BPF_LD+BPF_W+BPF_ABS, offsetof(struct seccomp_data, args[2])),
|
||||||
|
BPF_STMT(BPF_ALU+BPF_AND+BPF_K, O_APPEND),
|
||||||
|
BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, O_APPEND, 0, 3),
|
||||||
BPF_STMT(BPF_LD+BPF_W+BPF_ABS, offsetof(struct seccomp_data, args[1])),
|
BPF_STMT(BPF_LD+BPF_W+BPF_ABS, offsetof(struct seccomp_data, args[1])),
|
||||||
BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, (uintptr_t)journalfilename, 0, 1),
|
BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, (uintptr_t)journalfilename, 0, 1),
|
||||||
BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_ALLOW),
|
BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_ALLOW),
|
||||||
BPF_STMT(BPF_LD+BPF_W+BPF_ABS, offsetof(struct seccomp_data, args[2])),
|
|
||||||
BPF_STMT(BPF_ALU+BPF_AND+BPF_K, O_ACCMODE),
|
|
||||||
BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, O_RDONLY, 0, 1),
|
|
||||||
BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_ALLOW),
|
|
||||||
BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_KILL),
|
BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_KILL),
|
||||||
|
|
||||||
|
ALLOW_SYSCALL(newfstatat),
|
||||||
|
#endif
|
||||||
|
|
||||||
ALLOW_SYSCALL(close),
|
ALLOW_SYSCALL(close),
|
||||||
|
|
||||||
/* for syslog() */
|
/* for syslog() */
|
||||||
|
|||||||
Reference in New Issue
Block a user