~ubuntu-branches/ubuntu/maverick/postgresql-8.4/maverick-security

« back to all changes in this revision

Viewing changes to src/backend/utils/misc/guc.c

  • Committer: Bazaar Package Importer
  • Author(s): Martin Pitt
  • Date: 2010-05-15 13:31:46 UTC
  • mfrom: (1.2.4 upstream)
  • Revision ID: james.westby@ubuntu.com-20100515133146-kd8qmfietgxqvam0
Tags: 8.4.4-1
* Urgency medium due to security fixes.
* New upstream security/bug fix release:
  - Enforce restrictions in plperl using an opmask applied to the whole
    interpreter, instead of using "Safe.pm".
    Recent developments have convinced us that "Safe.pm" is too
    insecure to rely on for making plperl trustable. This change
    removes use of "Safe.pm" altogether, in favor of using a separate
    interpreter with an opcode mask that is always applied. Pleasant
    side effects of the change include that it is now possible to use
    Perl's strict pragma in a natural way in plperl, and that Perl's $a
    and $b variables work as expected in sort routines, and that
    function compilation is significantly faster. (CVE-2010-1169)
  - Prevent PL/Tcl from executing untrustworthy code from pltcl_modules.
    PL/Tcl's feature for autoloading Tcl code from a database table
    could be exploited for trojan-horse attacks, because there was no
    restriction on who could create or insert into that table. This
    change disables the feature unless pltcl_modules is owned by a
    superuser. (However, the permissions on the table are not checked,
    so installations that really need a less-than-secure modules table
    can still grant suitable privileges to trusted non-superusers.)
    Also, prevent loading code into the unrestricted "normal" Tcl
    interpreter unless we are really going to execute a pltclu
    function. (CVE-2010-1170)
  - Fix data corruption during WAL replay of ALTER ... SET TABLESPACE.
    When archive_mode is on, ALTER ... SET TABLESPACE generates a WAL
    record whose replay logic was incorrect. It could write the data to
    the wrong place, leading to possibly-unrecoverable data corruption.
    Data corruption would be observed on standby slaves, and could
    occur on the master as well if a database crash and recovery
    occurred after committing the ALTER and before the next checkpoint.
  - Fix possible crash if a cache reset message is received during
    rebuild of a relcache entry.
    This error was introduced in 8.4.3 while fixing a related failure.
  - Apply per-function GUC settings while running the language
    validator for the function. This avoids failures if the function's code
    is invalid without the setting; an example is that SQL functions may not
    parse if the search_path is not correct.
  - Do constraint exclusion for inherited "UPDATE" and "DELETE" target
    tables when constraint_exclusion = partition.
    Due to an oversight, this setting previously only caused constraint
    exclusion to be checked in "SELECT" commands.
  - Do not allow an unprivileged user to reset superuser-only parameter
    settings.
    Previously, if an unprivileged user ran ALTER USER ... RESET ALL
    for himself, or ALTER DATABASE ... RESET ALL for a database he
    owns, this would remove all special parameter settings for the user
    or database, even ones that are only supposed to be changeable by a
    superuser. Now, the "ALTER" will only remove the parameters that
    the user has permission to change.
  - Avoid possible crash during backend shutdown if shutdown occurs
    when a CONTEXT addition would be made to log entries.
    In some cases the context-printing function would fail because the
    current transaction had already been rolled back when it came time
    to print a log message.
  - Fix erroneous handling of %r parameter in recovery_end_command.
    The value always came out zero.
  - Ensure the archiver process responds to changes in archive_command
    as soon as possible.
  - Fix pl/pgsql's CASE statement to not fail when the case expression
    is a query that returns no rows.
  - Update pl/perl's "ppport.h" for modern Perl versions.
  - Fix assorted memory leaks in pl/python.
  - Handle empty-string connect parameters properly in ecpg.
  - Prevent infinite recursion in psql when expanding a variable that
    refers to itself.
  - Fix psql's \copy to not add spaces around a dot within \copy
    (select ...).
    Addition of spaces around the decimal point in a numeric literal
    would result in a syntax error.
  - Avoid formatting failure in psql when running in a locale context
    that doesn't match the client_encoding.
  - Fix unnecessary "GIN indexes do not support whole-index scans"
    errors for unsatisfiable queries using "contrib/intarray" operators.
  - Ensure that "contrib/pgstattuple" functions respond to cancel
    interrupts promptly.

Show diffs side-by-side

added added

removed removed

Lines of Context:
10
10
 * Written by Peter Eisentraut <peter_e@gmx.net>.
11
11
 *
12
12
 * IDENTIFICATION
13
 
 *        $PostgreSQL: pgsql/src/backend/utils/misc/guc.c,v 1.505.2.5 2010/02/25 13:26:26 mha Exp $
 
13
 *        $PostgreSQL: pgsql/src/backend/utils/misc/guc.c,v 1.505.2.6 2010/03/25 14:44:51 alvherre Exp $
14
14
 *
15
15
 *--------------------------------------------------------------------
16
16
 */
7042
7042
                free(name);
7043
7043
                if (value)
7044
7044
                        free(value);
 
7045
                pfree(s);
7045
7046
        }
7046
7047
}
7047
7048
 
7176
7177
                        && val[strlen(name)] == '=')
7177
7178
                        continue;
7178
7179
 
7179
 
                /* else add it to the output array */
7180
 
                if (newarray)
7181
 
                {
7182
 
                        newarray = array_set(newarray, 1, &index,
7183
 
                                                                 d,
7184
 
                                                                 false,
7185
 
                                                                 -1 /* varlenarray */ ,
7186
 
                                                                 -1 /* TEXT's typlen */ ,
7187
 
                                                                 false /* TEXT's typbyval */ ,
7188
 
                                                                 'i' /* TEXT's typalign */ );
7189
 
                }
7190
 
                else
7191
 
                        newarray = construct_array(&d, 1,
7192
 
                                                                           TEXTOID,
7193
 
                                                                           -1, false, 'i');
7194
 
 
7195
 
                index++;
 
7180
 
 
7181
                /* else add it to the output array */
 
7182
                if (newarray)
 
7183
                {
 
7184
                        newarray = array_set(newarray, 1, &index,
 
7185
                                                                 d,
 
7186
                                                                 false,
 
7187
                                                                 -1 /* varlenarray */ ,
 
7188
                                                                 -1 /* TEXT's typlen */ ,
 
7189
                                                                 false /* TEXT's typbyval */ ,
 
7190
                                                                 'i' /* TEXT's typalign */ );
 
7191
                }
 
7192
                else
 
7193
                        newarray = construct_array(&d, 1,
 
7194
                                                                           TEXTOID,
 
7195
                                                                           -1, false, 'i');
 
7196
 
 
7197
                index++;
 
7198
        }
 
7199
 
 
7200
        return newarray;
 
7201
}
 
7202
 
 
7203
/*
 
7204
 * Given a GUC array, delete all settings from it that our permission
 
7205
 * level allows: if superuser, delete them all; if regular user, only
 
7206
 * those that are PGC_USERSET
 
7207
 */
 
7208
ArrayType *
 
7209
GUCArrayReset(ArrayType *array)
 
7210
{
 
7211
        ArrayType  *newarray;
 
7212
        int                     i;
 
7213
        int                     index;
 
7214
 
 
7215
        /* if array is currently null, nothing to do */
 
7216
        if (!array)
 
7217
                return NULL;
 
7218
 
 
7219
        /* if we're superuser, we can delete everything */
 
7220
        if (superuser())
 
7221
                return NULL;
 
7222
 
 
7223
        newarray = NULL;
 
7224
        index = 1;
 
7225
 
 
7226
        for (i = 1; i <= ARR_DIMS(array)[0]; i++)
 
7227
        {
 
7228
                Datum           d;
 
7229
                char       *val;
 
7230
                char       *eqsgn;
 
7231
                bool            isnull;
 
7232
                struct config_generic *gconf;
 
7233
 
 
7234
                d = array_ref(array, 1, &i,
 
7235
                                          -1 /* varlenarray */ ,
 
7236
                                          -1 /* TEXT's typlen */ ,
 
7237
                                          false /* TEXT's typbyval */ ,
 
7238
                                          'i' /* TEXT's typalign */ ,
 
7239
                                          &isnull);
 
7240
 
 
7241
                if (isnull)
 
7242
                        continue;
 
7243
                val = TextDatumGetCString(d);
 
7244
 
 
7245
                eqsgn = strchr(val, '=');
 
7246
                *eqsgn = '\0';
 
7247
 
 
7248
                gconf = find_option(val, false, WARNING);
 
7249
                if (!gconf)
 
7250
                        continue;
 
7251
 
 
7252
                /* note: superuser-ness was already checked above */
 
7253
                /* skip entry if OK to delete */
 
7254
                if (gconf->context == PGC_USERSET)
 
7255
                        continue;
 
7256
 
 
7257
                /* XXX do we need to worry about database owner? */
 
7258
 
 
7259
                /* else add it to the output array */
 
7260
                if (newarray)
 
7261
                {
 
7262
                        newarray = array_set(newarray, 1, &index,
 
7263
                                                                 d,
 
7264
                                                                 false,
 
7265
                                                                 -1 /* varlenarray */ ,
 
7266
                                                                 -1 /* TEXT's typlen */ ,
 
7267
                                                                 false /* TEXT's typbyval */ ,
 
7268
                                                                 'i' /* TEXT's typalign */ );
 
7269
                }
 
7270
                else
 
7271
                        newarray = construct_array(&d, 1,
 
7272
                                                                           TEXTOID,
 
7273
                                                                           -1, false, 'i');
 
7274
 
 
7275
                index++;
 
7276
                pfree(val);
7196
7277
        }
7197
7278
 
7198
7279
        return newarray;