Kafel support
This commit is contained in:
parent
ee7de33531
commit
551ed4ca05
3
.gitmodules
vendored
Normal file
3
.gitmodules
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
[submodule "kafel"]
|
||||
path = kafel
|
||||
url = https://github.com/google/kafel.git
|
17
Makefile
17
Makefile
@ -34,6 +34,11 @@ ifdef DEBUG
|
||||
CFLAGS += -g -ggdb -gdwarf-4
|
||||
endif
|
||||
|
||||
ifneq ("$(wildcard kafel/include/kafel.h)","")
|
||||
CFLAGS += -I./kafel/include/ -DUSE_KAFEL
|
||||
LIBS += kafel/libkafel.a
|
||||
endif
|
||||
|
||||
ifeq ("$(wildcard /usr/include/libnl3/netlink/route/link/macvlan.h)","/usr/include/libnl3/netlink/route/link/macvlan.h")
|
||||
CFLAGS += -DNSJAIL_NL3_WITH_MACVLAN -I/usr/include/libnl3
|
||||
LDFLAGS += -lnl-3 -lnl-route-3
|
||||
@ -44,11 +49,19 @@ endif
|
||||
|
||||
all: $(BIN)
|
||||
|
||||
$(BIN): $(OBJS)
|
||||
$(CC) -o $(BIN) $(OBJS) $(LDFLAGS)
|
||||
$(BIN): $(OBJS) $(LIBS)
|
||||
$(CC) -o $(BIN) $(OBJS) $(LIBS) $(LDFLAGS)
|
||||
|
||||
ifneq ("$(wildcard kafel/Makefile)","")
|
||||
kafel/libkafel.a:
|
||||
$(MAKE) -C kafel
|
||||
endif
|
||||
|
||||
clean:
|
||||
$(RM) core Makefile.bak $(OBJS) $(BIN)
|
||||
ifneq ("$(wildcard kafel/Makefile)","")
|
||||
$(MAKE) -C kafel clean
|
||||
endif
|
||||
|
||||
depend:
|
||||
makedepend -Y. -- -- $(SRCS)
|
||||
|
30
cmdline.c
30
cmdline.c
@ -41,6 +41,10 @@
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#if USE_KAFEL
|
||||
#include <kafel.h>
|
||||
#endif
|
||||
|
||||
#include "log.h"
|
||||
#include "util.h"
|
||||
|
||||
@ -294,6 +298,7 @@ bool cmdlineParse(int argc, char *argv[], struct nsjconf_t * nsjconf)
|
||||
.cgroup_mem_mount = "/sys/fs/cgroup/memory",
|
||||
.cgroup_mem_parent = "NSJAIL",
|
||||
.cgroup_mem_max = (size_t)0,
|
||||
.seccomp_fprog = {0, NULL},
|
||||
.iface_no_lo = false,
|
||||
.iface = NULL,
|
||||
.iface_vs_ip = "0.0.0.0",
|
||||
@ -375,6 +380,9 @@ bool cmdlineParse(int argc, char *argv[], struct nsjconf_t * nsjconf)
|
||||
{{"tmpfsmount", required_argument, NULL, 'T'}, "List of mountpoints to be mounted as RW/tmpfs inside the container. Can be specified multiple times. Supports 'dest' syntax"},
|
||||
{{"tmpfs_size", required_argument, NULL, 0x0602}, "Number of bytes to allocate for tmpfsmounts (default: 4194304)"},
|
||||
{{"disable_proc", no_argument, NULL, 0x0603}, "Disable mounting /proc in the jail"},
|
||||
#if USE_KAFEL
|
||||
{{"seccomp_policy", required_argument, NULL, 0x0901}, "Seccomp policy filename"},
|
||||
#endif
|
||||
{{"cgroup_mem_max", required_argument, NULL, 0x0801}, "Maximum number of bytes to use in the group (default: '0' - disabled)"},
|
||||
{{"cgroup_mem_mount", required_argument, NULL, 0x0802}, "Location of memory cgroup FS (default: '/sys/fs/cgroup/memory')"},
|
||||
{{"cgroup_mem_parent", required_argument, NULL, 0x0803}, "Which pre-existing memory cgroup to use as a parent (default: 'NSJAIL')"},
|
||||
@ -620,6 +628,28 @@ bool cmdlineParse(int argc, char *argv[], struct nsjconf_t * nsjconf)
|
||||
case 0x803:
|
||||
nsjconf->cgroup_mem_parent = optarg;
|
||||
break;
|
||||
#if USE_KAFEL
|
||||
case 0x901:
|
||||
{
|
||||
FILE *f = fopen(optarg, "r");
|
||||
if (f == NULL) {
|
||||
LOG_E("Could not open policy file `%s'", optarg);
|
||||
return false;
|
||||
}
|
||||
kafel_ctxt_t ctxt = kafel_ctxt_create();
|
||||
kafel_set_input_file(ctxt, f);
|
||||
if (kafel_compile(ctxt, &nsjconf->seccomp_fprog) != 0) {
|
||||
fclose(f);
|
||||
LOG_E("Could not compile policy: %s",
|
||||
kafel_error_msg(ctxt));
|
||||
kafel_ctxt_destroy(&ctxt);
|
||||
return false;
|
||||
}
|
||||
fclose(f);
|
||||
kafel_ctxt_destroy(&ctxt);
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
cmdlineUsage(argv[0], custom_opts);
|
||||
return false;
|
||||
|
2
common.h
2
common.h
@ -23,6 +23,7 @@
|
||||
#define NS_COMMON_H
|
||||
|
||||
#include <limits.h>
|
||||
#include <linux/filter.h>
|
||||
#include <netinet/ip6.h>
|
||||
#include <stdbool.h>
|
||||
#include <sys/queue.h>
|
||||
@ -135,6 +136,7 @@ struct nsjconf_t {
|
||||
const char *cgroup_mem_mount;
|
||||
const char *cgroup_mem_parent;
|
||||
size_t cgroup_mem_max;
|
||||
struct sock_fprog seccomp_fprog;
|
||||
TAILQ_HEAD(envlist, charptr_t) envs;
|
||||
TAILQ_HEAD(pidslist, pids_t) pids;
|
||||
TAILQ_HEAD(mountptslist, mounts_t) mountpts;
|
||||
|
1
kafel
Submodule
1
kafel
Submodule
@ -0,0 +1 @@
|
||||
Subproject commit f7b486817e9a738c0705ecabc5ba6f8204a32685
|
77
sandbox.c
77
sandbox.c
@ -37,54 +37,59 @@
|
||||
* A demo policy, it disallows syslog and ptrace syscalls, both in 32 and 64
|
||||
* modes
|
||||
*/
|
||||
static bool sandboxPrepareAndCommit(void)
|
||||
static bool sandboxPrepareAndCommit(struct nsjconf_t *nsjconf)
|
||||
{
|
||||
#if defined(__x86_64__) || defined(__i386__)
|
||||
struct bpf_labels l = {.count = 0 };
|
||||
struct sock_filter filter[] = {
|
||||
LOAD_ARCH,
|
||||
JEQ32(AUDIT_ARCH_I386, JUMP(&l, label_i386)),
|
||||
JEQ32(AUDIT_ARCH_X86_64, JUMP(&l, label_x86_64)),
|
||||
if (nsjconf->seccomp_fprog.filter == NULL) {
|
||||
struct bpf_labels l = {.count = 0 };
|
||||
struct sock_filter filter[] = {
|
||||
LOAD_ARCH,
|
||||
JEQ32(AUDIT_ARCH_I386, JUMP(&l, label_i386)),
|
||||
JEQ32(AUDIT_ARCH_X86_64, JUMP(&l, label_x86_64)),
|
||||
|
||||
/* I386 */
|
||||
LABEL(&l, label_i386),
|
||||
LOAD_SYSCALL_NR,
|
||||
/* I386 */
|
||||
LABEL(&l, label_i386),
|
||||
LOAD_SYSCALL_NR,
|
||||
#define __NR_syslog_32 103
|
||||
#define __NR_uselib_32 86
|
||||
JEQ32(__NR_syslog_32, ERRNO(ENOENT)),
|
||||
JEQ32(__NR_uselib_32, KILL),
|
||||
ALLOW,
|
||||
JEQ32(__NR_syslog_32, ERRNO(ENOENT)),
|
||||
JEQ32(__NR_uselib_32, KILL),
|
||||
ALLOW,
|
||||
|
||||
/* X86_64 */
|
||||
LABEL(&l, label_x86_64),
|
||||
LOAD_SYSCALL_NR,
|
||||
/* X86_64 */
|
||||
LABEL(&l, label_x86_64),
|
||||
LOAD_SYSCALL_NR,
|
||||
#define __NR_syslog_64 103
|
||||
#define __NR_uselib_64 134
|
||||
JEQ32(__NR_syslog_64, ERRNO(ENOENT)),
|
||||
JEQ32(__NR_uselib_64, KILL),
|
||||
ALLOW,
|
||||
};
|
||||
|
||||
struct sock_fprog prog = {
|
||||
.filter = filter,
|
||||
.len = (unsigned short)(sizeof(filter) / sizeof(filter[0])),
|
||||
};
|
||||
if (bpf_resolve_jumps(&l, filter, sizeof(filter) / sizeof(*filter)) != 0) {
|
||||
LOG_W("bpf_resolve_jumps() failed");
|
||||
return false;
|
||||
JEQ32(__NR_syslog_64, ERRNO(ENOENT)),
|
||||
JEQ32(__NR_uselib_64, KILL),
|
||||
ALLOW,
|
||||
};
|
||||
/* *INDENT-OFF* */
|
||||
nsjconf->seccomp_fprog = (struct sock_fprog) {
|
||||
.filter = filter,
|
||||
.len = (unsigned short)(sizeof(filter) / sizeof(filter[0])),
|
||||
};
|
||||
/* *INDENT-ON* */
|
||||
if (bpf_resolve_jumps(&l, filter, sizeof(filter) / sizeof(*filter)) != 0) {
|
||||
LOG_W("bpf_resolve_jumps() failed");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
#endif /* defined(__x86_64__) || defined(__i386__) */
|
||||
if (nsjconf->seccomp_fprog.filter != NULL) {
|
||||
#ifndef PR_SET_NO_NEW_PRIVS
|
||||
#define PR_SET_NO_NEW_PRIVS 38
|
||||
#endif /* PR_SET_NO_NEW_PRIVS */
|
||||
if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0)) {
|
||||
PLOG_W("prctl(PR_SET_NO_NEW_PRIVS, 1) failed");
|
||||
return false;
|
||||
if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0)) {
|
||||
PLOG_W("prctl(PR_SET_NO_NEW_PRIVS, 1) failed");
|
||||
return false;
|
||||
}
|
||||
if (prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &nsjconf->seccomp_fprog, 0, 0)) {
|
||||
PLOG_W("prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER) failed");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog, 0, 0)) {
|
||||
PLOG_W("prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER) failed");
|
||||
return false;
|
||||
}
|
||||
#endif /* defined(__x86_64__) || defined(__i386__) */
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -93,7 +98,7 @@ bool sandboxApply(struct nsjconf_t * nsjconf)
|
||||
if (nsjconf->apply_sandbox == false) {
|
||||
return true;
|
||||
}
|
||||
if (sandboxPrepareAndCommit() == false) {
|
||||
if (sandboxPrepareAndCommit(nsjconf) == false) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
Loading…
Reference in New Issue
Block a user