Commits

dgc  committed c8dd362

wise SIGCHLD protection - idea from Joerg Barfurth at Sun

  • Participants
  • Parent commits d8c6582

Comments (0)

Files changed (1)

File pam_provision.c

 #include <errno.h>
 #include <fcntl.h>
 #include <unistd.h>
+#include <signal.h>
 #include <sys/types.h>
 #include <sys/wait.h>
 #include <sys/socket.h>
 	int stat;
 	int sock[2];
 	int null;
+	void *oldhandler = NULL;
 
 	memset(msgbuf, 0, sizeof(msgbuf));
 
 		return PAM_SYSTEM_ERR;
 	}
 
+	/* restore default sigchld handler, saving the prior handler.
+	 * (sigchld handler might have been set by the pam agent.) */
+	oldhandler = signal(SIGCHLD, SIG_DFL);
+
 	pid = fork();
 	if (pid < 0) {
+		/* error - restore original sigchld handler and return */
+		signal(SIGCHLD, oldhandler);
 		msg(ctx, LOG_WARNING, "cannnot fork: %s", strerror(errno));
 		close(sock[0]);
 		close(sock[1]);
 	}
 
 	else if (pid == 0) {
-		/* child */
+		/* child - keep sig_dfl sigchld handler until death do it part */
 		close(sock[0]);
 		null = open("/dev/null", O_RDONLY);
 		dup2(null, 0);
 	}
 
 	else {
-		/* parent */
+		/* parent - restore sigchld handler -only- after reaping child */
 		FILE *fp;
 		char buf[1024];
 		char *p;
 		close(sock[0]);
 
 		waitpid(pid, &stat, 0);
+		signal(SIGCHLD, oldhandler);
 		if (WEXITSTATUS(stat) != 0) {
 			msg(ctx, LOG_INFO, "exec returned %d", WEXITSTATUS(stat));
 			return PAM_SYSTEM_ERR;