2017-08-10 Security Update Release

Posted on 2017-08-10 by PostgreSQL Global Development Group

The PostgreSQL Global Development Group has released an update to all supported versions of our database system, including 9.6.4, 9.5.8, 9.4.13, 9.3.18, and 9.2.22. This release fixes three security issues. It also patches over 50 other bugs reported over the last three months. Users who are affected by the below security issues should update as soon as possible. Users affected by CVE-2017-7547 will need to perform additional steps after upgrading to resolve the issue. Other users should plan to update at the next convenient downtime.

Security Issues

Three security vulnerabilities have been closed by this release:

  • CVE-2017-7546: Empty password accepted in some authentication methods
  • CVE-2017-7547: The "pg_user_mappings" catalog view discloses passwords to users lacking server privileges
  • CVE-2017-7548: lo_put() function ignores ACLs

CVE-2017-7546: Empty password accepted in some authentication methods

libpq, and by extension any connection driver that utilizes libpq, ignores empty passwords and does not transmit them to the server. When using libpq or a libpq-based connection driver to perform password-based authentication methods, it would appear that setting an empty password would be the equivalent of disabling password login. However, using a non-libpq based connection driver could allow a client with an empty password to log in.

To fix this issue, this update disables empty passwords from being submitted in any of the password-based authentication methods. The server will reject any empty passwords from being set on accounts.

CVE-2017-7547: The "pg_user_mappings" catalog view discloses passwords to users lacking server privileges

This fix pertains to the usage of the foreign data wrapper functionality, particularly for the user mapping feature.

Before this fix, a user had access to see the options in pg_user_mappings even if the user did not have the USAGE permission on the associated foreign server. This meant that a user could see details such as a password that might have been set by the server administrator rather than the user.

This fix will only fix the behavior in newly created clusters utilizing initdb. To fix this issue on existing systems, you will need to follow the below steps. For more details, please see the release notes.

  1. In your postgresql.conf file, add the following:

    allow_system_table_mods = true
    
  2. After adding that line, you will need to restart your PostgreSQL cluster.

  3. In each database of the cluster, run the following commands as a superuser:

    SET search_path = pg_catalog;
    CREATE OR REPLACE VIEW pg_user_mappings AS
    SELECT
        U.oid       AS umid,
        S.oid       AS srvid,
        S.srvname   AS srvname,
        U.umuser    AS umuser,
        CASE WHEN U.umuser = 0 THEN
            'public'
        ELSE
            A.rolname
        END AS usename,
        CASE WHEN (U.umuser <> 0 AND A.rolname = current_user
                     AND (pg_has_role(S.srvowner, 'USAGE')
                          OR has_server_privilege(S.oid, 'USAGE')))
                    OR (U.umuser = 0 AND pg_has_role(S.srvowner, 'USAGE'))
                    OR (SELECT rolsuper FROM pg_authid WHERE rolname = current_user)
                    THEN U.umoptions
                 ELSE NULL END AS umoptions
    FROM pg_user_mapping U
    LEFT JOIN pg_authid A ON (A.oid = U.umuser)
    JOIN pg_foreign_server S ON (U.umserver = S.oid);
    
  4. You also need to run the command on your template0 and template1 databases, otherwise the vulnerability will exist in future databases that you create.

    First, you will need to allow template0 to accept connections. In PostgreSQL 9.5 you can run the following:

    ALTER DATABASE template0 WITH ALLOW_CONNECTIONS true;
    

    In PostgreSQL 9.4 and below, you will have to run this command:

    UPDATE pg_database SET datallowconn = true WHERE datname = 'template0';
    

    Then, in your template0 and template1 databases, run the commands as describe in Step 3

    When you are done, you will need to disallow connections from template0. In PostgreSQL 9.5, you can run the following:

    ALTER DATABASE template0 WITH ALLOW_CONNECTIONS false;
    

    In PostgreSQL 9.4 and below, you will have to run the following:

    UPDATE pg_database SET datallowconn = false WHERE datname = 'template0';
    
  5. Remove the following line from your postgresql.conf file:

    allow_system_table_mods = false
    
  6. Restart your PostgreSQL cluster

For more details, please see the release notes.

CVE-2017-7548: lo_put() function ignores ACLs

The lo_put() function should require the same permissions as lowrite(), but there was a missing permission check which would allow any user to change the data in a large object.

To fix this, the lo_put() function was changed to check the UPDATE privileges on the target object.

Bug Fixes and Improvements

This update also fixes a number of bugs reported in the last few months. Some of these issues affect only version 9.6, but many affect all supported versions:

  • pg_upgrade: corrected the documentation about the process for upgrading standby servers to ensure the primary and standbys synchronized safely. Also includes a fix to ensure the last WAL record does not have "wal_level = minimum" which would prevent standbys from connecting upon restart
  • Fix for issue with a concurrent locking race condition that could cause some of the updates to fail
  • Several fixes for low probability data corruption scenarios
  • Fix to prevent crash when sorting more than one billion tuples in-memory
  • Fix on Windows to retry creating a process if shared memory addresses could not be allocated, typically caused from antivirus software interference
  • Fix in libpq to ensure that failed connection attempts using GSS/SASL and SSPI authentication are reset properly
  • Fixes for SSL connection handling and logging
  • Fix to allow window functions to be used in sub-SELECT statements that are within the arguments of an aggregate function
  • Allow parallelism in the query plan when COPY when copying from a query
  • Several fixes to ALTER TABLE
  • Fix to ensure that ALTER USER ... SET and ALTER ROLE ... SET accepts the same syntax variants
  • Fixes for the statistics collector, ensuring statistics requests made just after a postmaster shutdown request will be written to disk
  • Fix possible creation of an invalid WAL segment during standby promotion
  • Several walsender / walreceiver fixes, particularly around signal handling and shutdowns / restarts
  • Several logic decoding fixes, including removing leakage of small subtransactions to disk
  • Allow a CHECK constraints to be initially NOT VALID when executing CREATE FOREIGN TABLE
  • Fixes to postgres_fdw for applying changes promptly after ALTER SERVER / ALTER USER MAPPING commands and improving ability to escape from an unresponsive server
  • Several fixes for pg_dump and pg_restore, including a fix for pg_dump output to stdout on Windows
  • Fix pg_basebackup output to stdout on Windows, similar to the fix for pg_dump
  • Fix pg_rewind to correctly handle files exceeding 2GB, though files of such size should rarely appear in a data directory
  • Several fixes for building PostgreSQL with Microsoft Visual C (MSVC), primarily around sourcing libraries

EOL Warning for Version 9.2

PostgreSQL version 9.2 will be End-of-Life in September, 2017. The project expects to only release one more update for that version. We urge users to start planning an upgrade to a later version of PostgreSQL as soon as possible. See our Versioning Policy for more information.

Updating

All PostgreSQL update releases are cumulative. As with other minor releases, users are not required to dump and reload their database or use pg_upgrade in order to apply this update release; you may simply shut down PostgreSQL and update its binaries.

Links: