aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorToni Uhlig <matzeton@googlemail.com>2018-05-20 16:15:17 +0200
committerToni Uhlig <matzeton@googlemail.com>2018-05-20 16:15:17 +0200
commit50bb59a86d354f775f78198b7ecf27ce5300dacf (patch)
tree36bb89490d64eff22e16385a04911cc8bf9ecf62
parent9c8dc27ee791b24e7325fa065cb57fa9b1339d11 (diff)
POTD skeleton #66.
Signed-off-by: Toni Uhlig <matzeton@googlemail.com>
-rw-r--r--src/capabilities.c31
-rw-r--r--src/capabilities.h2
-rw-r--r--src/jail.c3
-rw-r--r--src/main.c5
-rw-r--r--src/protocol_ssh.c10
-rw-r--r--src/pseccomp.c43
-rw-r--r--src/pseccomp.h4
7 files changed, 83 insertions, 15 deletions
diff --git a/src/capabilities.c b/src/capabilities.c
index a393efc..57658cc 100644
--- a/src/capabilities.c
+++ b/src/capabilities.c
@@ -238,13 +238,38 @@ int caps_default_filter(void)
const char *const capstrs[] = {
"sys_module", "sys_rawio", "sys_boot",
"sys_nice", "sys_tty_config",
+ "mknod", "sys_admin", "sys_resource",
+ "sys_time"
+ };
+
+ for (i = 0; i < SIZEOF(capstrs); ++i ) {
+ code = caps_find_name(capstrs[i]);
+ if (code < 0)
+ goto errexit;
+ if (prctl(PR_CAPBSET_DROP, code, 0, 0, 0) < 0)
+ goto errexit;
+ }
+
+ return 0;
+errexit:
+ E("%s", "Can not drop capabilities");
+ exit(EXIT_FAILURE);
+}
+
+int caps_jail_filter(void)
+{
+ size_t i;
+ int code;
+ const char *const capstrs[] = {
#ifdef CAP_SYSLOG
"syslog",
#endif
- "mknod", "sys_admin"
+ "audit_control", "audit_read", "audit_write",
+ "sys_ptrace", "sys_pacct", "sys_chroot", "sys_nice",
+ "sys_tty_config"
};
- for (i = 0; i < SIZEOF(capstrs); ++i ) {
+ for (i = 0; i < SIZEOF(capstrs); ++i) {
code = caps_find_name(capstrs[i]);
if (code < 0)
goto errexit;
@@ -255,7 +280,7 @@ int caps_default_filter(void)
return 0;
errexit:
E("%s", "Can not drop capabilities");
- exit(1);
+ exit(EXIT_FAILURE);
}
void caps_drop_all(void)
diff --git a/src/capabilities.h b/src/capabilities.h
index 2ca8c4f..e345804 100644
--- a/src/capabilities.h
+++ b/src/capabilities.h
@@ -12,6 +12,8 @@ void caps_drop_dac_override(int noprofile);
int caps_default_filter(void);
+int caps_jail_filter(void);
+
void caps_drop_all(void);
void caps_set(uint64_t caps);
diff --git a/src/jail.c b/src/jail.c
index bcf8755..450051f 100644
--- a/src/jail.c
+++ b/src/jail.c
@@ -145,6 +145,7 @@ pid_t jail_daemonize(event_ctx **ev_ctx, jail_ctx *ctx[], size_t siz)
E_STRERR("%s", "Jail daemonize");
return -1;
case 0:
+ caps_jail_filter();
jail_mainloop(ev_ctx, (const jail_ctx **) ctx, siz);
break;
}
@@ -350,7 +351,7 @@ static int jail_childfn(prisoner_process *ctx)
);
pseccomp_set_immutable();
- pseccomp_init(&psc);
+ pseccomp_init(&psc, 0);
if (pseccomp_jail_rules(psc))
FATAL("%s", "SECCOMP: adding jail rules");
pseccomp_free(&psc);
diff --git a/src/main.c b/src/main.c
index bb9a5c8..310dbe5 100644
--- a/src/main.c
+++ b/src/main.c
@@ -74,7 +74,7 @@ int main(int argc, char *argv[])
}
caps_default_filter();
- pseccomp_init(&psc);
+ pseccomp_init(&psc, 0);
if (pseccomp_default_rules(psc))
FATAL("%s", "SECCOMP: adding default rules");
pseccomp_free(&psc);
@@ -148,8 +148,9 @@ int main(int argc, char *argv[])
if (child_pid == jail_pid ||
child_pid == rdr_pid) {
E2("%s daemon with pid %d terminated, exiting",
- (child_pid == jail_pid ? "Jail" : "Server"),
+ (child_pid == jail_pid ? "Jail" : "Redirector"),
(child_pid == jail_pid ? jail_pid : rdr_pid));
+ kill(0, SIGTERM);
break;
}
}
diff --git a/src/protocol_ssh.c b/src/protocol_ssh.c
index da60f9f..1941dbb 100644
--- a/src/protocol_ssh.c
+++ b/src/protocol_ssh.c
@@ -10,6 +10,7 @@
#include "protocol_ssh.h"
#include "protocol.h"
+#include "pseccomp.h"
#include "utils.h"
#include "log.h"
@@ -118,6 +119,7 @@ int ssh_on_listen(protocol_ctx *ctx)
pid_t p;
int s;
ssh_data *d = (ssh_data *) ctx->src.data;
+ pseccomp_ctx *psc = NULL;
if (ssh_bind_options_set(d->sshbind, SSH_BIND_OPTIONS_BINDADDR,
ctx->src.host_buf))
@@ -144,6 +146,14 @@ int ssh_on_listen(protocol_ctx *ctx)
ssh_bind_get_fd(d->sshbind));
return 1;
case 0:
+ pseccomp_set_immutable();
+ pseccomp_init(&psc, 1);
+ s = pseccomp_protocol_rules(psc);
+ pseccomp_free(&psc);
+ if (s) {
+ E_STRERR("%s", "Could not add seccomp rules");
+ return -1;
+ }
if (change_default_user_group()) {
E_STRERR("%s", "Change user/group");
return -1;
diff --git a/src/pseccomp.c b/src/pseccomp.c
index 59414d7..da39cbb 100644
--- a/src/pseccomp.c
+++ b/src/pseccomp.c
@@ -6,6 +6,8 @@
#include "log.h"
#include "utils.h"
+static int pseccomp_using_valgrind(void);
+
static const int default_allowed_syscalls[] = {
SCMP_SYS(rt_sigreturn), SCMP_SYS(rt_sigprocmask),
SCMP_SYS(rt_sigaction), SCMP_SYS(time), SCMP_SYS(nanosleep),
@@ -38,6 +40,10 @@ static const int default_allowed_syscalls[] = {
SCMP_SYS(sethostname), SCMP_SYS(uname), SCMP_SYS(arch_prctl)
};
+static const int protocol_disabled_syscalls[] = {
+ SCMP_SYS(execve), SCMP_SYS(execveat)
+};
+
static const int jail_allowed_syscalls[] = {
SCMP_SYS(rt_sigreturn), SCMP_SYS(rt_sigprocmask),
SCMP_SYS(rt_sigaction), SCMP_SYS(time), SCMP_SYS(nanosleep),
@@ -64,7 +70,16 @@ static const int jail_allowed_syscalls[] = {
};
-int pseccomp_init(pseccomp_ctx **ctx)
+static int pseccomp_using_valgrind(void)
+{
+ if (RUNNING_ON_VALGRIND) {
+ W("%s", "SECCOMP: running on valgrind, disabled");
+ return 1;
+ }
+ return 0;
+}
+
+int pseccomp_init(pseccomp_ctx **ctx, unsigned int defact_allow)
{
assert(ctx);
@@ -73,7 +88,9 @@ int pseccomp_init(pseccomp_ctx **ctx)
assert(*ctx);
memset(*ctx, 0, sizeof(**ctx));
- (*ctx)->sfilter = seccomp_init(SCMP_ACT_ERRNO(EINVAL));
+ (*ctx)->sfilter = seccomp_init(
+ (defact_allow ? SCMP_ACT_ALLOW : SCMP_ACT_ERRNO(EINVAL))
+ );
return 0;
}
@@ -102,10 +119,8 @@ int pseccomp_default_rules(pseccomp_ctx *ctx)
{
size_t i;
- if (RUNNING_ON_VALGRIND) {
- W("%s", "SECCOMP: running on valgrind, disabled");
+ if (pseccomp_using_valgrind())
return 0;
- }
for (i = 0; i < SIZEOF(default_allowed_syscalls); ++i)
seccomp_rule_add(ctx->sfilter, SCMP_ACT_ALLOW,
@@ -114,14 +129,26 @@ int pseccomp_default_rules(pseccomp_ctx *ctx)
return seccomp_load(ctx->sfilter);
}
+int pseccomp_protocol_rules(pseccomp_ctx *ctx)
+{
+ size_t i;
+
+ if (pseccomp_using_valgrind())
+ return 0;
+
+ for (i = 0; i < SIZEOF(protocol_disabled_syscalls); ++i)
+ seccomp_rule_add(ctx->sfilter, SCMP_ACT_ERRNO(EINVAL),
+ protocol_disabled_syscalls[i], 0);
+
+ return seccomp_load(ctx->sfilter);
+}
+
int pseccomp_jail_rules(pseccomp_ctx *ctx)
{
size_t i;
- if (RUNNING_ON_VALGRIND) {
- W("%s", "SECCOMP: running on valgrind, disabled");
+ if (pseccomp_using_valgrind())
return 0;
- }
for (i = 0; i < SIZEOF(jail_allowed_syscalls); ++i)
seccomp_rule_add(ctx->sfilter, SCMP_ACT_ALLOW,
diff --git a/src/pseccomp.h b/src/pseccomp.h
index d208275..0bb5b2c 100644
--- a/src/pseccomp.h
+++ b/src/pseccomp.h
@@ -8,7 +8,7 @@ typedef struct pseccomp_ctx {
} pseccomp_ctx;
-int pseccomp_init(pseccomp_ctx **ctx);
+int pseccomp_init(pseccomp_ctx **ctx, unsigned int defact_allow);
void pseccomp_free(pseccomp_ctx **ctx);
@@ -16,6 +16,8 @@ int pseccomp_set_immutable(void);
int pseccomp_default_rules(pseccomp_ctx *ctx);
+int pseccomp_protocol_rules(pseccomp_ctx *ctx);
+
int pseccomp_jail_rules(pseccomp_ctx *ctx);
#endif