Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/external/bsd/openpam/dist/lib CVE-2014-3879: Incorrect error...



details:   https://anonhg.NetBSD.org/src/rev/d302f16afbf8
branches:  trunk
changeset: 329682:d302f16afbf8
user:      christos <christos%NetBSD.org@localhost>
date:      Tue Jun 03 20:21:32 2014 +0000

description:
CVE-2014-3879: Incorrect error handling in PAM policy parser:
Missing module files were treated as soft failures leading to
unexpected behavior if policy files were copied between hosts with
differently installed modules or in the short period during upgrades
when module files were being replaced.

diffstat:

 external/bsd/openpam/dist/lib/openpam_configure.c |  42 ++++++++++++++++++----
 1 files changed, 34 insertions(+), 8 deletions(-)

diffs (127 lines):

diff -r 6c82b0e16b2b -r d302f16afbf8 external/bsd/openpam/dist/lib/openpam_configure.c
--- a/external/bsd/openpam/dist/lib/openpam_configure.c Tue Jun 03 20:01:34 2014 +0000
+++ b/external/bsd/openpam/dist/lib/openpam_configure.c Tue Jun 03 20:21:32 2014 +0000
@@ -1,8 +1,8 @@
-/*     $NetBSD: openpam_configure.c,v 1.7 2014/01/03 22:49:21 joerg Exp $      */
+/*     $NetBSD: openpam_configure.c,v 1.8 2014/06/03 20:21:32 christos Exp $   */
 
 /*-
  * Copyright (c) 2001-2003 Networks Associates Technology, Inc.
- * Copyright (c) 2004-2012 Dag-Erling Smørgrav
+ * Copyright (c) 2004-2014 Dag-Erling Smørgrav
  * All rights reserved.
  *
  * This software was developed for the FreeBSD Project by ThinkSec AS and
@@ -195,6 +195,7 @@
                        openpam_log(PAM_LOG_ERROR,
                            "%s(%d): missing or invalid facility",
                            filename, lineno);
+                       errno = EINVAL;
                        goto fail;
                }
                if (facility != fclt && facility != PAM_FACILITY_ANY) {
@@ -210,18 +211,28 @@
                                openpam_log(PAM_LOG_ERROR,
                                    "%s(%d): missing or invalid service name",
                                    filename, lineno);
+                               errno = EINVAL;
                                goto fail;
                        }
                        if (wordv[i] != NULL) {
                                openpam_log(PAM_LOG_ERROR,
                                    "%s(%d): garbage at end of line",
                                    filename, lineno);
+                               errno = EINVAL;
                                goto fail;
                        }
                        ret = openpam_load_chain(pamh, servicename, fclt);
                        FREEV(wordc, wordv);
-                       if (ret < 0)
+                       if (ret < 0) {
+                               /*
+                                * Bogus errno, but this ensures that the
+                                * outer loop does not just ignore the
+                                * error and keep searching.
+                                */
+                               if (errno == ENOENT)
+                                       errno = EINVAL;
                                goto fail;
+                       }
                        continue;
                }
 
@@ -231,6 +242,7 @@
                        openpam_log(PAM_LOG_ERROR,
                            "%s(%d): missing or invalid control flag",
                            filename, lineno);
+                       errno = EINVAL;
                        goto fail;
                }
 
@@ -240,6 +252,7 @@
                        openpam_log(PAM_LOG_ERROR,
                            "%s(%d): missing or invalid module name",
                            filename, lineno);
+                       errno = EINVAL;
                        goto fail;
                }
 
@@ -249,8 +262,11 @@
                this->flag = ctlf;
 
                /* load module */
-               if ((this->module = openpam_load_module(modulename)) == NULL)
+               if ((this->module = openpam_load_module(modulename)) == NULL) {
+                       if (errno == ENOENT)
+                               errno = ENOEXEC;
                        goto fail;
+               }
 
                /*
                 * The remaining items in wordv are the module's
@@ -283,7 +299,11 @@
         * The loop ended because openpam_readword() returned NULL, which
         * can happen for four different reasons: an I/O error (ferror(f)
         * is true), a memory allocation failure (ferror(f) is false,
-        * errno is non-zero)
+        * feof(f) is false, errno is non-zero), the file ended with an
+        * unterminated quote or backslash escape (ferror(f) is false,
+        * feof(f) is true, errno is non-zero), or the end of the file was
+        * reached without error (ferror(f) is false, feof(f) is true,
+        * errno is zero).
         */
        if (ferror(f) || errno != 0)
                goto syserr;
@@ -404,6 +424,9 @@
                }
                ret = openpam_load_file(pamh, service, facility,
                    filename, style);
+               /* success */
+               if (ret > 0)
+                       RETURNN(ret);
                /* the file exists, but an error occurred */
                if (ret == -1 && errno != ENOENT)
                        RETURNN(ret);
@@ -413,7 +436,8 @@
        }
 
        /* no hit */
-       RETURNN(0);
+       errno = ENOENT;
+       RETURNN(-1);
 }
 
 /*
@@ -434,8 +458,10 @@
                openpam_log(PAM_LOG_ERROR, "invalid service name");
                RETURNC(PAM_SYSTEM_ERR);
        }
-       if (openpam_load_chain(pamh, service, PAM_FACILITY_ANY) < 0)
-               goto load_err;
+       if (openpam_load_chain(pamh, service, PAM_FACILITY_ANY) < 0) {
+               if (errno != ENOENT)
+                       goto load_err;
+       }
        for (fclt = 0; fclt < PAM_NUM_FACILITIES; ++fclt) {
                if (pamh->chains[fclt] != NULL)
                        continue;



Home | Main Index | Thread Index | Old Index