Changeset 795 in openpam for trunk/lib


Ignore:
Timestamp:
Jun 3, 2014, 9:27:48 PM (6 years ago)
Author:
Dag-Erling Smørgrav
Message:

In openpam_parse_chain():

  1. Finish a comment which was meant to describe the four different termination conditions for the loop in openpam_parse_chain() but ended in mid-sentence.
  1. Ensure that errno is consistently set to EINVAL if a syntax error is encountered in the policy file.
  1. If openpam_load_module() fails because the module could not be loaded, set errno to ENOEXEC instead of ENOENT. This closes a hole where a missing module or a typo in a module name would cause the corresponding chain to fail open. Normally, if the policy exists but cannot be loaded, openpam_load_chain() will return an error, and openpam_configure() will discard any partially constructed chains. However, openpam_load_chain() interprets ENOENT to mean that the policy was not found, so it does not immediately return an error, the partially-loaded chain is not discarded, and the policy is incorrectly considered to have been successfully loaded.
  1. Ensure that errors encountered while parsing an included policy are correctly propagated to the original policy, and that ENOENT while processing an include directive is a hard error, not a soft error.

CVE-2014-3879

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/lib/libpam/openpam_configure.c

    r745 r795  
    11/*-
    22 * Copyright (c) 2001-2003 Networks Associates Technology, Inc.
    3  * Copyright (c) 2004-2012 Dag-Erling Smørgrav
     3 * Copyright (c) 2004-2014 Dag-Erling Smørgrav
    44 * All rights reserved.
    55 *
     
    194194                            "%s(%d): missing or invalid facility",
    195195                            filename, lineno);
     196                        errno = EINVAL;
    196197                        goto fail;
    197198                }
     
    209210                                    "%s(%d): missing or invalid service name",
    210211                                    filename, lineno);
     212                                errno = EINVAL;
    211213                                goto fail;
    212214                        }
     
    215217                                    "%s(%d): garbage at end of line",
    216218                                    filename, lineno);
     219                                errno = EINVAL;
    217220                                goto fail;
    218221                        }
    219222                        ret = openpam_load_chain(pamh, servicename, fclt);
    220223                        FREEV(wordc, wordv);
    221                         if (ret < 0)
     224                        if (ret < 0) {
     225                                /*
     226                                 * Bogus errno, but this ensures that the
     227                                 * outer loop does not just ignore the
     228                                 * error and keep searching.
     229                                 */
     230                                if (errno == ENOENT)
     231                                        errno = EINVAL;
    222232                                goto fail;
     233                        }
    223234                        continue;
    224235                }
     
    230241                            "%s(%d): missing or invalid control flag",
    231242                            filename, lineno);
     243                        errno = EINVAL;
    232244                        goto fail;
    233245                }
     
    239251                            "%s(%d): missing or invalid module name",
    240252                            filename, lineno);
     253                        errno = EINVAL;
    241254                        goto fail;
    242255                }
     
    248261
    249262                /* load module */
    250                 if ((this->module = openpam_load_module(modulename)) == NULL)
     263                if ((this->module = openpam_load_module(modulename)) == NULL) {
     264                        if (errno == ENOENT)
     265                                errno = ENOEXEC;
    251266                        goto fail;
     267                }
    252268
    253269                /*
     
    282298         * can happen for four different reasons: an I/O error (ferror(f)
    283299         * is true), a memory allocation failure (ferror(f) is false,
    284          * errno is non-zero)
     300         * feof(f) is false, errno is non-zero), the file ended with an
     301         * unterminated quote or backslash escape (ferror(f) is false,
     302         * feof(f) is true, errno is non-zero), or the end of the file was
     303         * reached without error (ferror(f) is false, feof(f) is true,
     304         * errno is zero).
    285305         */
    286306        if (ferror(f) || errno != 0)
     
    407427                ret = openpam_load_file(pamh, service, facility,
    408428                    filename, style);
     429                /* success */
     430                if (ret > 0)
     431                        RETURNN(ret);
    409432                /* the file exists, but an error occurred */
    410433                if (ret == -1 && errno != ENOENT)
     
    416439
    417440        /* no hit */
    418         RETURNN(0);
     441        errno = ENOENT;
     442        RETURNN(-1);
    419443}
    420444
     
    437461                RETURNC(PAM_SYSTEM_ERR);
    438462        }
    439         if (openpam_load_chain(pamh, service, PAM_FACILITY_ANY) < 0)
    440                 goto load_err;
     463        if (openpam_load_chain(pamh, service, PAM_FACILITY_ANY) < 0) {
     464                if (errno != ENOENT)
     465                        goto load_err;
     466        }
    441467        for (fclt = 0; fclt < PAM_NUM_FACILITIES; ++fclt) {
    442468                if (pamh->chains[fclt] != NULL)
Note: See TracChangeset for help on using the changeset viewer.