Added support for seccomp (untested)

This commit is contained in:
Nikos Mavrogiannopoulos
2013-02-12 18:01:25 +01:00
parent 356da3fbe4
commit 8cba144e77
6 changed files with 108 additions and 6 deletions

View File

@@ -141,6 +141,9 @@
/* Define to 1 if you have the <libgen.h> header file. */
#undef HAVE_LIBGEN_H
/* Define if you have the libseccomp library. */
#undef HAVE_LIBSECCOMP
/* Define if you have the libutil library. */
#undef HAVE_LIBUTIL

View File

@@ -64,6 +64,20 @@ gl_INIT
AC_LIB_HAVE_LINKFLAGS(util,, [#include <utmpx.h>], [pututxline(0);])
AC_ARG_ENABLE(seccomp,
AS_HELP_STRING([--disable-seccomp], [unconditionally disable seccomp]),
seccomp_enabled=$enableval, seccomp_enabled=yes)
if [ test "$seccomp_enabled" = "yes" ];then
AC_LIB_HAVE_LINKFLAGS(seccomp,, [#include <linux/seccomp.h>
#include <seccomp.h>], [seccomp_init(0);])
if [ test -z "$LIBSECCOMP" ];then
seccomp_enabled="no"
else
seccomp_enabled="yes"
fi
fi
enable_local_libopts=yes
NEED_LIBOPTS_DIR=true
LIBOPTS_CHECK([libopts])
@@ -84,5 +98,6 @@ AC_MSG_NOTICE([summary of build options:
CFlags: ${CFLAGS}
GDBM backend: ${gdbm_enabled}
PAM backend: ${pam_enabled}
seccomp: ${seccomp_enabled}
])

View File

@@ -18,13 +18,14 @@ ocserv_SOURCES = main.c main-auth.c worker-vpn.c worker-auth.c tlslib.c \
vpn.h cookies.h tlslib.h http-parser/http_parser.h log.c tun.c tun.h \
config.c pam.c pam.h worker-resume.c worker.h main-resume.c main.h \
main-user.c cookies-gdbm.c cookies-hash.c worker-misc.c setproctitle.h \
setproctitle.c \
setproctitle.c worker-privs.c \
$(CCAN_SOURCES)
ocserv_SOURCES += ocserv-args.def ocserv-args.c ocserv-args.h
ocserv_LDADD = ../gl/libgnu.a ../libopts/libopts.a
ocserv_LDADD += $(LIBGNUTLS_LIBS) $(GDBM_LIBS) $(PAM_LIBS)
ocserv_LDADD += $(LIBGNUTLS_LIBS) $(GDBM_LIBS) $(PAM_LIBS) $(LIBUTIL) \
$(LIBSECCOMP)
ocserv-args.c ocserv-args.h: $(srcdir)/ocserv-args.def
-autogen ocserv-args.def

79
src/worker-privs.c Normal file
View File

@@ -0,0 +1,79 @@
/*
* Copyright (C) 2013 Nikos Mavrogiannopoulos
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <config.h>
#include <worker.h>
#ifdef HAVE_LIBSECCOMP
#include <seccomp.h>
#include <errno.h>
int disable_system_calls(struct worker_st *ws)
{
int ret, e;
scmp_filter_ctx ctx;
ctx = seccomp_init(SCMP_ACT_KILL);
if (ctx == NULL) {
oclog(ws, LOG_WARNING, "could not initialize seccomp");
return -1;
}
#define ADD_SYSCALL(name) \
ret = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(name), 0); \
if (ret < 0) { \
e = errno; \
oclog(ws, LOG_WARNING, "could not add " #name " to seccomp filter: %s", strerror(e)); \
ret = -1; \
goto fail; \
}
ADD_SYSCALL(time);
ADD_SYSCALL(recvmsg);
ADD_SYSCALL(sendmsg);
ADD_SYSCALL(read);
ADD_SYSCALL(write);
ADD_SYSCALL(select);
ADD_SYSCALL(alarm);
ADD_SYSCALL(close);
ADD_SYSCALL(exit);
ADD_SYSCALL(exit_group);
ADD_SYSCALL(ioctl);
ADD_SYSCALL(send);
ADD_SYSCALL(recv);
ret = seccomp_load(ctx);
if (ret < 0) {
oclog(ws, LOG_ERR, "could not load seccomp filter");
ret = -1;
goto fail;
}
seccomp_release(ctx);
ret = 0;
fail:
seccomp_release(ctx);
return ret;
}
#else
int disable_system_calls(struct worker_st *ws)
{
return 0;
}
#endif

View File

@@ -35,7 +35,6 @@
#include <net/if.h>
#include <netinet/in.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <signal.h>
@@ -320,10 +319,14 @@ void vpn_server(struct worker_st* ws)
if (ws->config->auth_timeout)
alarm(ws->config->auth_timeout);
ret = disable_system_calls(ws);
if (ret < 0) {
oclog(ws, LOG_ERR, "could not disable system calls (seccomp error)");
exit(1);
}
syslog(LOG_INFO, "Accepted connection from %s",
human_addr((void*)&ws->remote_addr, ws->remote_addr_len,
buf, sizeof(buf)));
oclog(ws, LOG_INFO, "accepted connection");
if (ws->remote_addr_len == sizeof(struct sockaddr_in))
ws->proto = AF_INET;
else

View File

@@ -99,5 +99,6 @@ ssize_t tun_write(int sockfd, const void *buf, size_t len);
int send_tun_mtu(worker_st *ws, unsigned int mtu);
int handle_worker_commands(struct worker_st *ws);
int disable_system_calls(struct worker_st *ws);
#endif