socsvn commit: r223746 - soc2011/kibab/freebsd-src-head/usr.sbin/syslogd

kibab at FreeBSD.org kibab at FreeBSD.org
Sun Jun 26 19:22:04 UTC 2011


Author: kibab
Date: Sun Jun 26 19:22:02 2011
New Revision: 223746
URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=223746

Log:
  Task-9: Initial support of capabilities usage in syslogd

Modified:
  soc2011/kibab/freebsd-src-head/usr.sbin/syslogd/syslogd.c

Modified: soc2011/kibab/freebsd-src-head/usr.sbin/syslogd/syslogd.c
==============================================================================
--- soc2011/kibab/freebsd-src-head/usr.sbin/syslogd/syslogd.c	Sun Jun 26 19:14:21 2011	(r223745)
+++ soc2011/kibab/freebsd-src-head/usr.sbin/syslogd/syslogd.c	Sun Jun 26 19:22:02 2011	(r223746)
@@ -75,6 +75,7 @@
 #define	TIMERINTVL	30		/* interval for checking flush, mark */
 #define	TTYMSGTIME	1		/* timeout passed to ttymsg */
 
+#include <sys/capability.h>
 #include <sys/param.h>
 #include <sys/ioctl.h>
 #include <sys/mman.h>
@@ -303,6 +304,7 @@
 static int	needdofsync = 0; /* Are any file(s) waiting to be fsynced? */
 static struct pidfh *pfh;
 
+static int child_pid = 0;      /* For parent process, child PID */
 volatile sig_atomic_t MarkSet, WantDie;
 
 static int	allowaddr(char *);
@@ -337,6 +339,9 @@
 static void	timedout(int);
 static void	double_rbuf(int);
 
+static void     parent_huphdl(int);
+static void     parent_duty(int);
+
 int
 main(int argc, char *argv[])
 {
@@ -495,6 +500,29 @@
 	if (NumAllowed)
 		endservent();
 
+	int fork_count = 0; /* XXX For debug purposes only, remove in production code! */
+	int chpid;
+	if(feature_present("security_capabilities")) {
+	  dprintf("Running with Capsicum support!\n");
+	  do {
+	    chpid = fork();
+	    fork_count++;
+
+	    if(chpid) {         /* Parent process */
+	      child_pid = chpid; /* Init global variable */
+	      (void)signal(SIGHUP, parent_huphdl);
+	      /* tuck my process id away */
+	      pidfile_write(pfh);
+	      
+	      parent_duty(chpid);
+	    } else { /* Child process */
+	      setproctitle("child process (capability mode)");
+	    }
+	    if(fork_count>10)
+	      errx(1, "ACHTUNG, high fork count");
+	  } while(chpid);
+	  dprintf("Child continued to run as usual!\n");
+	}
 	consfile.f_type = F_CONSOLE;
 	(void)strlcpy(consfile.f_un.f_fname, ctty + sizeof _PATH_DEV - 1,
 	    sizeof(consfile.f_un.f_fname));
@@ -570,11 +598,22 @@
 		dprintf("can't open %s (%d)\n", _PATH_KLOG, errno);
 
 	/* tuck my process id away */
-	pidfile_write(pfh);
+	/*
+	 * pidfile_write(pfh);  this should be done earlier if forking. 
+	 * Without forking it doesn't hurt to do it earlier anyway
+	 */
 
 	dprintf("off & running....\n");
 
 	init(0);
+
+	/* Revoke ambient privs */
+	if(cap_enter() < 0) {
+	  err(32, "Could not enter capability mode!");
+	} else {
+	  dprintf("FreeBSD capability mode enabled!\n");
+	}
+	
 	/* prevent SIGHUP and SIGCHLD handlers from running in parallel */
 	sigemptyset(&mask);
 	sigaddset(&mask, SIGCHLD);
@@ -677,6 +716,36 @@
 		free(fdsr);
 }
 
+/**
+ * Set up as SIGHUP handler in the parent process
+ */
+static void parent_huphdl(int signo) {
+  dprintf("SIGHUP handler called, trying to kill the child\n");
+  if(kill(child_pid, SIGTERM) < 0) {
+    warnx("Cannot SIGTERM child process, WTF?!");
+  }
+}
+
+/**
+ * Watch after child process
+ */
+static void parent_duty(int ch_pid) {
+  int status = 0;
+  
+  setproctitle("master process");
+  dprintf("Parent: waiting for child...\n");
+  if(waitpid(child_pid, &status, 0) <0) {
+    errx(1, "waitpid() is unsuccessful, exiting");
+  };
+
+  /* Examine the exit cause */
+  if(WIFSIGNALED(status))
+    dprintf("Child exited due to signal -- this is suspicious, as all expected signals might have been intercepted by the child?!\n");
+  if(WIFEXITED(status))
+    dprintf("Child exited normally\n");
+  /* XXX Maybe we should check for special return code that indicates misconfiguration? */
+}
+
 static void
 unmapped(struct sockaddr *sa)
 {


More information about the svn-soc-all mailing list