4e2b970
diff -up Linux-PAM-1.0.4/modules/pam_unix/pam_unix_passwd.c.safeguards Linux-PAM-1.0.4/modules/pam_unix/pam_unix_passwd.c
342194f
--- Linux-PAM-1.0.4/modules/pam_unix/pam_unix_passwd.c.safeguards	2009-03-17 11:25:11.000000000 +0100
342194f
+++ Linux-PAM-1.0.4/modules/pam_unix/pam_unix_passwd.c	2009-03-17 11:25:11.000000000 +0100
4e2b970
@@ -139,7 +139,7 @@ static int _unix_run_update_binary(pam_h
4e2b970
     const char *fromwhat, const char *towhat, int remember)
4e2b970
 {
4e2b970
     int retval, child, fds[2];
4e2b970
-    void (*sighandler)(int) = NULL;
4e2b970
+    struct sigaction newsa, oldsa;
4e2b970
 
4e2b970
     D(("called."));
4e2b970
     /* create a pipe for the password */
4e2b970
@@ -157,13 +157,15 @@ static int _unix_run_update_binary(pam_h
4e2b970
 	 * The "noreap" module argument is provided so that the admin can
4e2b970
 	 * override this behavior.
4e2b970
 	 */
4e2b970
-	sighandler = signal(SIGCHLD, SIG_DFL);
4e2b970
+        memset(&newsa, '\0', sizeof(newsa));
4e2b970
+        newsa.sa_handler = SIG_DFL;
4e2b970
+        sigaction(SIGCHLD, &newsa, &oldsa);
4e2b970
     }
4e2b970
 
4e2b970
     /* fork */
4e2b970
     child = fork();
4e2b970
     if (child == 0) {
4e2b970
-        size_t i=0;
4e2b970
+        int i=0;
4e2b970
         struct rlimit rlim;
4e2b970
 	static char *envp[] = { NULL };
4e2b970
 	char *args[] = { NULL, NULL, NULL, NULL, NULL, NULL };
4e2b970
@@ -171,15 +173,14 @@ static int _unix_run_update_binary(pam_h
4e2b970
 
4e2b970
 	/* XXX - should really tidy up PAM here too */
4e2b970
 
4e2b970
-	close(0); close(1);
4e2b970
 	/* reopen stdin as pipe */
4e2b970
-	close(fds[1]);
4e2b970
 	dup2(fds[0], STDIN_FILENO);
4e2b970
 
4e2b970
 	if (getrlimit(RLIMIT_NOFILE,&rlim)==0) {
4e2b970
-	  for (i=2; i < rlim.rlim_max; i++) {
4e2b970
-	    if ((unsigned int)fds[0] != i)
4e2b970
-	  	   close(i);
4e2b970
+	  if (rlim.rlim_max >= MAX_FD_NO)
4e2b970
+	    rlim.rlim_max = MAX_FD_NO;
4e2b970
+	  for (i = STDERR_FILENO + 1; i < (int)rlim.rlim_max; i++) {
4e2b970
+	    close(i);
4e2b970
 	  }
4e2b970
 	}
4e2b970
 
4e2b970
@@ -239,8 +240,8 @@ static int _unix_run_update_binary(pam_h
4e2b970
 	retval = PAM_AUTH_ERR;
4e2b970
     }
4e2b970
 
4e2b970
-    if (sighandler != SIG_ERR) {
4e2b970
-        (void) signal(SIGCHLD, sighandler);   /* restore old signal handler */
4e2b970
+    if (off(UNIX_NOREAP, ctrl)) {
4e2b970
+        sigaction(SIGCHLD, &oldsa, NULL);   /* restore old signal handler */
4e2b970
     }
4e2b970
 
4e2b970
     return retval;
4e2b970
diff -up Linux-PAM-1.0.4/modules/pam_unix/support.c.safeguards Linux-PAM-1.0.4/modules/pam_unix/support.c
342194f
--- Linux-PAM-1.0.4/modules/pam_unix/support.c.safeguards	2009-03-17 11:25:11.000000000 +0100
342194f
+++ Linux-PAM-1.0.4/modules/pam_unix/support.c	2009-03-17 11:25:11.000000000 +0100
4e2b970
@@ -396,7 +396,7 @@ static int _unix_run_helper_binary(pam_h
4e2b970
 				   unsigned int ctrl, const char *user)
4e2b970
 {
4e2b970
     int retval, child, fds[2];
4e2b970
-    void (*sighandler)(int) = NULL;
4e2b970
+    struct sigaction newsa, oldsa;
4e2b970
 
4e2b970
     D(("called."));
4e2b970
     /* create a pipe for the password */
4e2b970
@@ -414,7 +414,9 @@ static int _unix_run_helper_binary(pam_h
4e2b970
 	 * The "noreap" module argument is provided so that the admin can
4e2b970
 	 * override this behavior.
4e2b970
 	 */
4e2b970
-	sighandler = signal(SIGCHLD, SIG_DFL);
4e2b970
+        memset(&newsa, '\0', sizeof(newsa));
4e2b970
+	newsa.sa_handler = SIG_DFL;
4e2b970
+	sigaction(SIGCHLD, &newsa, &oldsa);
4e2b970
     }
4e2b970
 
4e2b970
     /* fork */
4e2b970
@@ -427,15 +429,14 @@ static int _unix_run_helper_binary(pam_h
4e2b970
 
4e2b970
 	/* XXX - should really tidy up PAM here too */
4e2b970
 
4e2b970
-	close(0); close(1);
4e2b970
 	/* reopen stdin as pipe */
4e2b970
-	close(fds[1]);
4e2b970
 	dup2(fds[0], STDIN_FILENO);
4e2b970
 
4e2b970
 	if (getrlimit(RLIMIT_NOFILE,&rlim)==0) {
4e2b970
-	  for (i=2; i < (int)rlim.rlim_max; i++) {
4e2b970
-		if (fds[0] != i)
4e2b970
-	  	   close(i);
4e2b970
+          if (rlim.rlim_max >= MAX_FD_NO)
4e2b970
+                rlim.rlim_max = MAX_FD_NO;
4e2b970
+	  for (i = STDERR_FILENO + 1; i < (int)rlim.rlim_max; i++) {
4e2b970
+	  	close(i);
4e2b970
 	  }
4e2b970
 	}
4e2b970
 
4e2b970
@@ -488,8 +489,8 @@ static int _unix_run_helper_binary(pam_h
4e2b970
 	retval = PAM_AUTH_ERR;
4e2b970
     }
4e2b970
 
4e2b970
-    if (sighandler != SIG_ERR) {
4e2b970
-        (void) signal(SIGCHLD, sighandler);   /* restore old signal handler */
4e2b970
+    if (off(UNIX_NOREAP, ctrl)) {
4e2b970
+        sigaction(SIGCHLD, &oldsa, NULL);   /* restore old signal handler */
4e2b970
     }
4e2b970
 
4e2b970
     D(("returning %d", retval));
4e2b970
diff -up Linux-PAM-1.0.4/modules/pam_unix/pam_unix_acct.c.safeguards Linux-PAM-1.0.4/modules/pam_unix/pam_unix_acct.c
4e2b970
--- Linux-PAM-1.0.4/modules/pam_unix/pam_unix_acct.c.safeguards	2009-03-03 10:00:31.000000000 +0100
342194f
+++ Linux-PAM-1.0.4/modules/pam_unix/pam_unix_acct.c	2009-03-17 15:14:09.000000000 +0100
4e2b970
@@ -65,7 +65,7 @@ int _unix_run_verify_binary(pam_handle_t
4e2b970
 	const char *user, int *daysleft)
4e2b970
 {
4e2b970
   int retval=0, child, fds[2];
4e2b970
-  void (*sighandler)(int) = NULL;
4e2b970
+  struct sigaction newsa, oldsa;
4e2b970
   D(("running verify_binary"));
4e2b970
 
4e2b970
   /* create a pipe for the messages */
342194f
@@ -85,29 +85,32 @@ int _unix_run_verify_binary(pam_handle_t
4e2b970
      * The "noreap" module argument is provided so that the admin can
4e2b970
      * override this behavior.
4e2b970
      */
4e2b970
-    sighandler = signal(SIGCHLD, SIG_DFL);
4e2b970
+     memset(&newsa, '\0', sizeof(newsa));
4e2b970
+     newsa.sa_handler = SIG_DFL;
4e2b970
+     sigaction(SIGCHLD, &newsa, &oldsa);
4e2b970
   }
4e2b970
 
4e2b970
   /* fork */
4e2b970
   child = fork();
4e2b970
   if (child == 0) {
4e2b970
-    size_t i=0;
4e2b970
+    int i=0;
4e2b970
     struct rlimit rlim;
4e2b970
     static char *envp[] = { NULL };
4e2b970
     char *args[] = { NULL, NULL, NULL, NULL };
4e2b970
 
4e2b970
-    close(0); close(1);
4e2b970
-    /* reopen stdin as pipe */
4e2b970
-    close(fds[0]);
4e2b970
+    /* reopen stdout as pipe */
4e2b970
     dup2(fds[1], STDOUT_FILENO);
342194f
+    /* and replace also the stdin so we do not exec the helper with
342194f
+       tty as stdin, it will not read anything from there anyway */
342194f
+    dup2(fds[0], STDIN_FILENO);
4e2b970
 
4e2b970
     /* XXX - should really tidy up PAM here too */
4e2b970
 
4e2b970
     if (getrlimit(RLIMIT_NOFILE,&rlim)==0) {
4e2b970
-      for (i=2; i < rlim.rlim_max; i++) {
4e2b970
-	if ((unsigned int)fds[1] != i) {
4e2b970
-	  close(i);
4e2b970
-	}
4e2b970
+      if (rlim.rlim_max >= MAX_FD_NO)
4e2b970
+        rlim.rlim_max = MAX_FD_NO;
4e2b970
+      for (i = STDERR_FILENO + 1; i < (int)rlim.rlim_max; i++) {
4e2b970
+	close(i);
4e2b970
       }
4e2b970
     }
4e2b970
 
342194f
@@ -126,7 +129,6 @@ int _unix_run_verify_binary(pam_handle_t
4e2b970
 
4e2b970
     pam_syslog(pamh, LOG_ERR, "helper binary execve failed: %m");
4e2b970
     /* should not get here: exit with error */
4e2b970
-    close (fds[1]);
4e2b970
     D(("helper binary is not available"));
4e2b970
     printf("-1\n");
4e2b970
     exit(PAM_AUTHINFO_UNAVAIL);
342194f
@@ -162,9 +164,11 @@ int _unix_run_verify_binary(pam_handle_t
4e2b970
     }
4e2b970
     close(fds[0]);
4e2b970
   }
4e2b970
-  if (sighandler != SIG_ERR) {
4e2b970
-    (void) signal(SIGCHLD, sighandler);   /* restore old signal handler */
4e2b970
+
4e2b970
+  if (off(UNIX_NOREAP, ctrl)) {
4e2b970
+        sigaction(SIGCHLD, &oldsa, NULL);   /* restore old signal handler */
4e2b970
   }
4e2b970
+
4e2b970
   D(("Returning %d",retval));
4e2b970
   return retval;
4e2b970
 }
4e2b970
diff -up Linux-PAM-1.0.4/modules/pam_unix/passverify.c.safeguards Linux-PAM-1.0.4/modules/pam_unix/passverify.c
4e2b970
--- Linux-PAM-1.0.4/modules/pam_unix/passverify.c.safeguards	2009-03-02 16:02:22.000000000 +0100
342194f
+++ Linux-PAM-1.0.4/modules/pam_unix/passverify.c	2009-03-17 11:25:11.000000000 +0100
4e2b970
@@ -117,7 +117,7 @@ verify_pwd_hash(const char *p, char *has
4e2b970
 		p = NULL;		/* no longer needed here */
4e2b970
 
4e2b970
 		/* the moment of truth -- do we agree with the password? */
4e2b970
-		D(("comparing state of pp[%s] and salt[%s]", pp, salt));
4e2b970
+		D(("comparing state of pp[%s] and hash[%s]", pp, hash));
4e2b970
 
4e2b970
 		if (pp && strcmp(pp, hash) == 0) {
4e2b970
 			retval = PAM_SUCCESS;
4e2b970
@@ -675,8 +675,13 @@ save_old_password(const char *forwho, co
4e2b970
 	}
4e2b970
     }
4e2b970
 
4e2b970
+    if (fflush(pwfile) || fsync(fileno(pwfile))) {
4e2b970
+	D(("fflush or fsync error writing entries to old passwords file: %m"));
4e2b970
+	err = 1;
4e2b970
+    }
4e2b970
+    
4e2b970
     if (fclose(pwfile)) {
4e2b970
-	D(("error writing entries to old passwords file: %m"));
4e2b970
+	D(("fclose error writing entries to old passwords file: %m"));
4e2b970
 	err = 1;
4e2b970
     }
4e2b970
 
4e2b970
@@ -795,8 +800,13 @@ unix_update_passwd(pam_handle_t *pamh, c
4e2b970
     }
4e2b970
     fclose(opwfile);
4e2b970
 
4e2b970
+    if (fflush(pwfile) || fsync(fileno(pwfile))) {
4e2b970
+	D(("fflush or fsync error writing entries to password file: %m"));
4e2b970
+	err = 1;
4e2b970
+    }
4e2b970
+    
4e2b970
     if (fclose(pwfile)) {
4e2b970
-	D(("error writing entries to password file: %m"));
4e2b970
+	D(("fclose error writing entries to password file: %m"));
4e2b970
 	err = 1;
4e2b970
     }
4e2b970
 
4e2b970
@@ -925,8 +935,13 @@ unix_update_shadow(pam_handle_t *pamh, c
4e2b970
     }
4e2b970
     fclose(opwfile);
4e2b970
 
4e2b970
+    if (fflush(pwfile) || fsync(fileno(pwfile))) {
4e2b970
+	D(("fflush or fsync error writing entries to shadow file: %m"));
4e2b970
+	err = 1;
4e2b970
+    }
4e2b970
+    
4e2b970
     if (fclose(pwfile)) {
4e2b970
-	D(("error writing entries to shadow file: %m"));
4e2b970
+	D(("fclose error writing entries to shadow file: %m"));
4e2b970
 	err = 1;
4e2b970
     }
4e2b970
 
4e2b970
@@ -1007,8 +1022,12 @@ su_sighandler(int sig)
4e2b970
 {
4e2b970
 #ifndef SA_RESETHAND
4e2b970
         /* emulate the behaviour of the SA_RESETHAND flag */
4e2b970
-        if ( sig == SIGILL || sig == SIGTRAP || sig == SIGBUS || sig = SIGSERV )
4e2b970
-                signal(sig, SIG_DFL);
4e2b970
+        if ( sig == SIGILL || sig == SIGTRAP || sig == SIGBUS || sig = SIGSERV ) {
4e2b970
+		struct sigaction sa;
4e2b970
+		memset(&sa, '\0, sizeof(sa));
4e2b970
+		sa.sa_handler = SIG_DFL;
4e2b970
+                sigaction(sig, &sa, NULL);
4e2b970
+	}
4e2b970
 #endif
4e2b970
         if (sig > 0) {
4e2b970
                 _exit(sig);
4e2b970
diff -up Linux-PAM-1.0.4/modules/pam_unix/support.h.safeguards Linux-PAM-1.0.4/modules/pam_unix/support.h
4e2b970
--- Linux-PAM-1.0.4/modules/pam_unix/support.h.safeguards	2008-01-23 16:35:13.000000000 +0100
342194f
+++ Linux-PAM-1.0.4/modules/pam_unix/support.h	2009-03-17 11:25:11.000000000 +0100
4e2b970
@@ -127,6 +127,7 @@ static const UNIX_Ctrls unix_args[UNIX_C
4e2b970
 
4e2b970
 #define UNIX_DEFAULTS  (unix_args[UNIX__NONULL].flag)
4e2b970
 
4e2b970
+#define MAX_FD_NO 2000000
4e2b970
 
4e2b970
 /* use this to free strings. ESPECIALLY password strings */
4e2b970