Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enable seccomp for zhm #136

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 21 additions & 1 deletion configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -264,7 +264,27 @@ if test "x$with_ares" != "xno"; then
AC_MSG_ERROR(libcares not found)))
fi
AC_SUBST(ARES_LIBS)


AC_ARG_WITH(seccomp,
[AS_HELP_STRING([--without-seccomp], [Disable seccomp])
AS_HELP_STRING([--with-seccomp=PREFIX], [Specify location of libseccomp])],
[seccomp="$withval"], [seccomp=maybe])
AS_IF([test "x$seccomp" != "xno"], [
AS_IF([test "x$seccomp" != "xyes" && test "x$seccomp" != "xmaybe"], [
CPPFLAGS="$CPPFLAGS -I$seccomp/include"
LDFLAGS="$LDFLAGS -I$seccomp/lib"
])
AC_CHECK_LIB(seccomp, seccomp_init, [
SECCOMP_LIBS="-lseccomp"
AC_DEFINE(HAVE_SECCOMP, 1,
[Define to compile with libseccomp support.])
], [
AS_IF([test "x$seccomp" != "xmaybe"],
AC_MSG_ERROR([libseccomp not found]))
])
])
AC_SUBST(SECCOMP_LIBS)

AC_PROG_GCC_TRADITIONAL
AC_FUNC_VPRINTF
AC_FUNC_GETPGRP
Expand Down
3 changes: 2 additions & 1 deletion debian/control
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ Build-Depends: debhelper (>= 5), libc-ares-dev, libkrb5-dev (>= 1.2.2-4),
comerr-dev, ss-dev, libreadline-dev | libreadline5-dev,
libx11-dev, libxt-dev, x11proto-core-dev, libncurses5-dev,
bison, libhesiod-dev, autotools-dev, python (>= 2.5), python-central,
autoconf, libtool, automake, git-core | git, devscripts
autoconf, libtool, automake, git-core | git, devscripts,
libseccomp-dev
Build-Conflicts: autoconf2.13
Standards-Version: 3.9.2.0
Homepage: http://zephyr.1ts.org/
Expand Down
3 changes: 2 additions & 1 deletion debian/rules
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@ PACKAGES:=-plibzephyr4 -pzephyr-clients -pzephyr-server -plibzephyr-dev -plibzep
export DH_OPTIONS
CONFIGURE_ROOT=--prefix=/usr --mandir=\$${prefix}/share/man \
--infodir=\$${prefix}/share/info --sysconfdir=/etc --datadir=/etc \
--with-cares=/usr --with-hesiod=/usr --enable-cmu-zwgcplus
--with-cares=/usr --with-hesiod=/usr --with-seccomp=/usr \
--enable-cmu-zwgcplus
CONFIGURE_krb5=--with-krb5=/usr
CONFIGURE_krb45=--with-krb4=/usr --with-krb5=/usr
CONFIGURE_krb=--with-krb4=/usr
Expand Down
3 changes: 2 additions & 1 deletion zhm/Makefile.in
Original file line number Diff line number Diff line change
Expand Up @@ -33,13 +33,14 @@ CFLAGS=@CFLAGS@
ALL_CFLAGS=${CFLAGS} -I${top_srcdir}/h -I${BUILDTOP}/h ${CPPFLAGS}
LDFLAGS=@LDFLAGS@
HESIOD_LIBS=@HESIOD_LIBS@
SECCOMP_LIBS=@SECCOMP_LIBS@

OBJS= timer.o queue.o zhm.o zhm_client.o zhm_server.o

all: zhm zhm.8

zhm: ${OBJS} ${LIBZEPHYR}
${LIBTOOL} --mode=link ${CC} ${LDFLAGS} -o $@ ${OBJS} ${LIBZEPHYR} ${HESIOD_LIBS} -lcom_err
${LIBTOOL} --mode=link ${CC} ${LDFLAGS} -o $@ ${OBJS} ${LIBZEPHYR} ${HESIOD_LIBS} -lcom_err ${SECCOMP_LIBS}

zhm.8: ${srcdir}/zhm.8.in Makefile
${editman} ${srcdir}/[email protected] > [email protected]
Expand Down
113 changes: 113 additions & 0 deletions zhm/zhm.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,18 @@
* $Id$
*
* Copyright (c) 1987,1991 by the Massachusetts Institute of Technology.
* Copyright 2019 Google LLC.
* For copying and distribution information, see the file
* "mit-copyright.h".
*/

#include "zhm.h"
#include <zephyr_version.h>

#ifdef HAVE_SECCOMP
#include <seccomp.h>
#endif

static const char rcsid_hm_c[] = "$Id$";

#ifdef HAVE_HESIOD
Expand Down Expand Up @@ -49,6 +54,9 @@ static void init_hm(void);
#ifndef DEBUG
static void detach(void);
#endif
#ifdef HAVE_SECCOMP
static int set_seccomp_enforcing(void);
#endif
static void send_stats(ZNotice_t *, struct sockaddr_in *);
static char *strsave(const char *);

Expand Down Expand Up @@ -164,6 +172,14 @@ main(int argc,
DPR2("zephyr server port: %u\n", ntohs(serv_sin.sin_port));
DPR2("zephyr client port: %u\n", ntohs(cli_port));

#ifdef HAVE_SECCOMP
if (set_seccomp_enforcing()) {
printf("Unable to enable seccomp; exiting.\n");
exit(ZERR_INTERNAL);
}
DPR("Seccomp enabled.\n");
#endif

/* Main loop */
for (;;) {
/* Wait for incoming packets or queue timeouts. */
Expand Down Expand Up @@ -519,6 +535,103 @@ stats_malloc(size_t size)
return p;
}

#ifdef HAVE_SECCOMP
static int
set_seccomp_enforcing(void)
{
scmp_filter_ctx ctx = seccomp_init(SCMP_ACT_KILL);
if (ctx == NULL) {
DPR("seccomp_init failed.");
return 1;
}
int r = 0;

#define ALLOW_SYSCALL(syscall) \
do { \
if ((r = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(syscall), \
0)) < 0) { \
Zperr(-r); \
goto out; \
} \
} while (0)

/* The main ZHM loop fundamentally consists of a select(2), a ZReceivePacket
* (a recvfrom(2)), and a ZSendPacket (a sendto(2)). */
ALLOW_SYSCALL(select);
ALLOW_SYSCALL(recvfrom);
ALLOW_SYSCALL(sendto);

/* If stuff breaks, we need to log with syslog(3). */
ALLOW_SYSCALL(openat);
ALLOW_SYSCALL(fstat);
ALLOW_SYSCALL(read);
ALLOW_SYSCALL(lseek);
ALLOW_SYSCALL(close);
ALLOW_SYSCALL(getpid);
ALLOW_SYSCALL(socket);
ALLOW_SYSCALL(connect);
ALLOW_SYSCALL(sendto);

/* We might also use com_err, which manipulates the terminal during its
* writes. */
ALLOW_SYSCALL(write);
ALLOW_SYSCALL(ioctl);

/* Exiting the process is okay. */
ALLOW_SYSCALL(exit_group);
ALLOW_SYSCALL(exit);

/* We might exit in response to a signal. */
ALLOW_SYSCALL(rt_sigreturn);
#ifdef __NR_sigreturn
ALLOW_SYSCALL(sigreturn);
#endif

/* When it's time to exit, we need to remove the PID file. */
ALLOW_SYSCALL(unlink);

#ifdef DEBUG
/* Logging stuff to stderr (with DPR and DPR2) is okay. write(2) has already
* been allowed above, so don't add it again. */
/* ALLOW_SYSCALL(write); */
#endif

#ifdef HAVE_HESIOD
/* If a Zephyr server goes offline; we need to query Hesiod for a new
* server. Some of these syscalls have already been allowed above, so don't
* add them again. */
ALLOW_SYSCALL(brk);
ALLOW_SYSCALL(getuid);
ALLOW_SYSCALL(geteuid);
ALLOW_SYSCALL(getgid);
ALLOW_SYSCALL(getegid);
/* ALLOW_SYSCALL(openat); */
/* ALLOW_SYSCALL(fstat); */
ALLOW_SYSCALL(mmap);
/* ALLOW_SYSCALL(close); */
/* ALLOW_SYSCALL(getpid); */
ALLOW_SYSCALL(stat);
/* ALLOW_SYSCALL(read); */
/* ALLOW_SYSCALL(socket); */
/* ALLOW_SYSCALL(connect); */
ALLOW_SYSCALL(poll);
/* ALLOW_SYSCALL(sendto); */
/* ALLOW_SYSCALL(recvfrom); */
#endif

#undef ALLOW_SYSCALL

if ((r = seccomp_load(ctx)) < 0) {
Zperr(-r);
goto out;
}

out:
seccomp_release(ctx);
return r;
}
#endif

static void
send_stats(ZNotice_t *notice,
struct sockaddr_in *sin)
Expand Down