playground

Sandbox, container or whatever utilities for linux.
git clone https://pi.duncano.de/git/playground.git
Log | Files | Refs | README

commit 91c35e7bc29888bcd3e6cece5cc0f5e472155212
parent 4365f95854fd5d2777ff6053a7607ae0668d3184
Author: Duncaen <mail@duncano.de>
Date:   Sun, 19 Feb 2017 21:29:42 +0100

libpledge: make filter conditions more clear

This addes three different modes to the filter conditions 0, `FILTER_WHITELIST`
and `FILTER_BLACKLIST`.

Diffstat:
include/pledge.h | 37++++++++++++++++++++++++++++++-------
tests/pledge/Makefile | 2++
tests/pledge/test_filter_conditions.c | 39+++++++++++++++++++++++----------------
3 files changed, 55 insertions(+), 23 deletions(-)

diff --git a/include/pledge.h b/include/pledge.h @@ -26,27 +26,50 @@ #define PLEDGE_KEY 0x0000000002000000ULL #define PLEDGE_KERN 0x0000000004000000ULL +#define FILTER_WHITELIST 1 +#define FILTER_BLACKLIST 2 + #define _FLAG_DROPPED(x) \ ((oldflags&(x)) && (~flags&(x))) #define _FILTER_CHOWN \ - (!oldflags && !(flags&PLEDGE_CHOWNUID)) || _FLAG_DROPPED(PLEDGE_CHOWNUID) + (!oldflags && !(flags&PLEDGE_CHOWNUID)) \ + ? FILTER_WHITELIST \ + : 0 #define _FILTER_PRCTL \ - _FLAG_DROPPED(PLEDGE_PROC) + (oldflags && !(flags&PLEDGE_PROC)) || (!oldflags && !(flags&PLEDGE_PROC)) \ + ? FILTER_WHITELIST \ + : 0 #define _FILTER_SOCKET \ - (!oldflags && !(flags&PLEDGE_INET)^!(flags&PLEDGE_UNIX)) || \ - _FLAG_DROPPED(PLEDGE_INET) ^ _FLAG_DROPPED(PLEDGE_UNIX) + (!oldflags && !(flags&PLEDGE_INET)^!(flags&PLEDGE_UNIX)) \ + ? FILTER_WHITELIST \ + : _FLAG_DROPPED(PLEDGE_INET) ^ _FLAG_DROPPED(PLEDGE_UNIX) \ + ? FILTER_WHITELIST \ + : 0 #define _FILTER_KILL \ - (!oldflags && !(flags&PLEDGE_PROC)) || _FLAG_DROPPED(PLEDGE_PROC) + (!oldflags && !(flags&PLEDGE_PROC)) || _FLAG_DROPPED(PLEDGE_PROC) \ + ? FILTER_WHITELIST \ + : 0 #define _FILTER_FCNTL \ - !(oldflags && flags&PLEDGE_PROC) || _FLAG_DROPPED(PLEDGE_PROC) + !(oldflags && flags&PLEDGE_PROC) || _FLAG_DROPPED(PLEDGE_PROC) \ + ? FILTER_WHITELIST \ + : 0 #define _FILTER_IOCTL_ALWAYS \ - !oldflags + !oldflags || _FLAG_DROPPED(PLEDGE_IOCTL) \ + ? FILTER_WHITELIST \ + : 0 + +#define _FILTER_IOCTL_IOCTL \ + (!oldflags && (flags&PLEDGE_IOCTL)) \ + ? FILTER_WHITELIST \ + : _FLAG_DROPPED(PLEDGE_IOCTL) \ + ? FILTER_BLACKLIST \ + : 0 struct sock_fprog *pledge_whitelist(uint64_t); struct sock_fprog *pledge_blacklist(uint64_t, uint64_t); diff --git a/tests/pledge/Makefile b/tests/pledge/Makefile @@ -7,6 +7,8 @@ TEST=${SRCS:.c=} all: options tests clean +test_filter_conditions.o: ../../include/pledge.h + $(TEST) : % : %.o $(TEST): diff --git a/tests/pledge/test_filter_conditions.c b/tests/pledge/test_filter_conditions.c @@ -6,7 +6,7 @@ #define TEST(s, o, f, t, e) do { \ oldflags = (o); flags = (f); \ ((rv = (t)) == (e) ? pass++ : fail++); \ - printf("%s:%d: %-7s ", __FILE__, __LINE__, (s)); \ + printf("%s:%d: %-20s ", __FILE__, __LINE__, (s)); \ printf("%d %s %d%s\n", (e), (rv == (e)) ? "==" : "!=", rv, (rv != (e)) ? " <<<<<" : ""); \ } while(0) @@ -18,41 +18,48 @@ main() int rv, fail, pass; fail = pass = 0; - TEST("chown", PLEDGE_CHOWNUID, 0LLU, _FILTER_CHOWN, 1); + TEST("chown", PLEDGE_CHOWNUID, 0LLU, _FILTER_CHOWN, 0); TEST("chown", 0LLU, 0LLU, _FILTER_CHOWN, 1); TEST("chown", PLEDGE_CHOWNUID, PLEDGE_CHOWNUID, _FILTER_CHOWN, 0); TEST("chown", PLEDGED, 0LLU, _FILTER_CHOWN, 0); TEST("chown", 0LLU, PLEDGE_CHOWNUID, _FILTER_CHOWN, 0); - TEST("prctl", PLEDGE_PROC, 0LLU, _FILTER_PRCTL, 1); + TEST("prctl", PLEDGE_PROC, 0LLU, _FILTER_PRCTL, FILTER_WHITELIST); + TEST("prctl", 0LLU, PLEDGE_PROC, _FILTER_PRCTL, 0); + TEST("prctl", 0LLU, 0LLU, _FILTER_PRCTL, FILTER_WHITELIST); TEST("prctl", PLEDGE_PROC, PLEDGE_PROC, _FILTER_PRCTL, 0); - TEST("prctl", 0LLU, 0LLU, _FILTER_PRCTL, 0); - TEST("socket", PLEDGE_INET|PLEDGE_UNIX, PLEDGE_UNIX, _FILTER_SOCKET, 1); - TEST("socket", PLEDGE_INET|PLEDGE_UNIX, PLEDGE_INET, _FILTER_SOCKET, 1); - TEST("socket", 0LLU, PLEDGE_INET, _FILTER_SOCKET, 1); + TEST("socket", PLEDGE_INET|PLEDGE_UNIX, PLEDGE_UNIX, _FILTER_SOCKET, FILTER_WHITELIST); + TEST("socket", PLEDGE_INET|PLEDGE_UNIX, PLEDGE_INET, _FILTER_SOCKET, FILTER_WHITELIST); + TEST("socket", 0LLU, PLEDGE_INET, _FILTER_SOCKET, FILTER_WHITELIST); TEST("socket", 0LLU, PLEDGE_UNIX|PLEDGE_INET, _FILTER_SOCKET, 0); TEST("socket", PLEDGE_INET, PLEDGE_INET, _FILTER_SOCKET, 0); TEST("socket", PLEDGE_UNIX, PLEDGE_UNIX, _FILTER_SOCKET, 0); TEST("socket", PLEDGE_INET|PLEDGE_UNIX, PLEDGE_INET|PLEDGE_UNIX, _FILTER_SOCKET, 0); TEST("socket", 0LLU, 0LLU, _FILTER_SOCKET, 0); - TEST("kill", PLEDGE_PROC, 0LLU, _FILTER_KILL, 1); - TEST("kill", 0LLU, 0LLU, _FILTER_KILL, 1); + TEST("kill", PLEDGE_PROC, 0LLU, _FILTER_KILL, FILTER_WHITELIST); + TEST("kill", 0LLU, 0LLU, _FILTER_KILL, FILTER_WHITELIST); TEST("kill", PLEDGE_PROC, PLEDGE_PROC, _FILTER_KILL, 0); TEST("kill", 0LLU, PLEDGE_PROC, _FILTER_KILL, 0); - TEST("fcntl", 0LLU, 0LLU, _FILTER_FCNTL, 1); - TEST("fcntl", PLEDGE_PROC, 0LLU, _FILTER_FCNTL, 1); + TEST("fcntl", 0LLU, 0LLU, _FILTER_FCNTL, FILTER_WHITELIST); + TEST("fcntl", PLEDGE_PROC, 0LLU, _FILTER_FCNTL, FILTER_WHITELIST); TEST("fcntl", PLEDGE_PROC, PLEDGE_PROC, _FILTER_FCNTL, 0); - TEST("fcntl", 0LLU, 0LLU, _FILTER_FCNTL, 1); - TEST("fcntl", PLEDGE_PROC, 0LLU, _FILTER_FCNTL, 1); + TEST("fcntl", 0LLU, 0LLU, _FILTER_FCNTL, FILTER_WHITELIST); + TEST("fcntl", PLEDGE_PROC, 0LLU, _FILTER_FCNTL, FILTER_WHITELIST); TEST("fcntl", PLEDGE_PROC, PLEDGE_PROC, _FILTER_FCNTL, 0); - TEST("ioctl", 0LLU, 0LLU, _FILTER_IOCTL_ALWAYS, 1); - TEST("ioctl", 0LLU, PLEDGE_IOCTL, _FILTER_IOCTL_ALWAYS, 1); - TEST("ioctl", PLEDGE_IOCTL, PLEDGE_IOCTL, _FILTER_IOCTL_ALWAYS, 0); + TEST("ioctl always", 0LLU, 0LLU, _FILTER_IOCTL_ALWAYS, FILTER_WHITELIST); + TEST("ioctl always", 0LLU, PLEDGE_IOCTL, _FILTER_IOCTL_ALWAYS, FILTER_WHITELIST); + TEST("ioctl always", PLEDGE_IOCTL, 0LLU, _FILTER_IOCTL_ALWAYS, FILTER_WHITELIST); + TEST("ioctl always", PLEDGE_IOCTL, PLEDGE_IOCTL, _FILTER_IOCTL_ALWAYS, 0); + + TEST("ioctl ioctl", 0LLU, PLEDGE_IOCTL, _FILTER_IOCTL_IOCTL, FILTER_WHITELIST); + TEST("ioctl ioctl", PLEDGE_IOCTL, 0LLU, _FILTER_IOCTL_IOCTL, FILTER_BLACKLIST); + TEST("ioctl ioctl", 0LLU, 0LLU, _FILTER_IOCTL_IOCTL, 0); + TEST("ioctl ioctl", PLEDGE_IOCTL, PLEDGE_IOCTL, _FILTER_IOCTL_IOCTL, 0); printf("failed=%d passed=%d\n", fail, pass);