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

« back to all changes in this revision

Viewing changes to src/backend/postmaster/syslogger.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:
18
18
 *
19
19
 *
20
20
 * IDENTIFICATION
21
 
 *        $PostgreSQL: pgsql/src/backend/postmaster/syslogger.c,v 1.51.2.1 2009/11/19 02:45:40 tgl Exp $
 
21
 *        $PostgreSQL: pgsql/src/backend/postmaster/syslogger.c,v 1.51.2.3 2010/04/16 09:51:54 heikki Exp $
22
22
 *
23
23
 *-------------------------------------------------------------------------
24
24
 */
117
117
 
118
118
#ifdef WIN32
119
119
static HANDLE threadHandle = 0;
120
 
static CRITICAL_SECTION sysfileSection;
 
120
static CRITICAL_SECTION sysloggerSection;
121
121
#endif
122
122
 
123
123
/*
194
194
                 */
195
195
                close(fileno(stdout));
196
196
                close(fileno(stderr));
197
 
                dup2(fd, fileno(stdout));
198
 
                dup2(fd, fileno(stderr));
199
 
                close(fd);
 
197
                if (fd != -1)
 
198
                {
 
199
                        dup2(fd, fileno(stdout));
 
200
                        dup2(fd, fileno(stderr));
 
201
                        close(fd);
 
202
                }
200
203
        }
201
204
 
202
205
        /*
265
268
 
266
269
#ifdef WIN32
267
270
        /* Fire up separate data transfer thread */
268
 
        InitializeCriticalSection(&sysfileSection);
 
271
        InitializeCriticalSection(&sysloggerSection);
 
272
        EnterCriticalSection(&sysloggerSection);
269
273
 
270
274
        threadHandle = (HANDLE) _beginthreadex(NULL, 0, pipeThread, NULL, 0, NULL);
271
275
        if (threadHandle == 0)
420
424
                 * On Windows we leave it to a separate thread to transfer data and
421
425
                 * detect pipe EOF.  The main thread just wakes up once a second to
422
426
                 * check for SIGHUP and rotation conditions.
 
427
                 *
 
428
                 * Server code isn't generally thread-safe, so we ensure that only
 
429
                 * one of the threads is active at a time by entering the critical
 
430
                 * section whenever we're not sleeping.
423
431
                 */
 
432
                LeaveCriticalSection(&sysloggerSection);
 
433
 
424
434
                pg_usleep(1000000L);
 
435
 
 
436
                EnterCriticalSection(&sysloggerSection);
425
437
#endif   /* WIN32 */
426
438
 
427
439
                if (pipe_eof_seen)
908
920
        if (destination == LOG_DESTINATION_CSVLOG && csvlogFile == NULL)
909
921
                open_csvlogfile();
910
922
 
911
 
#ifdef WIN32
912
 
        EnterCriticalSection(&sysfileSection);
913
 
#endif
914
 
 
915
923
        logfile = destination == LOG_DESTINATION_CSVLOG ? csvlogFile : syslogFile;
916
924
        rc = fwrite(buffer, 1, count, logfile);
917
925
 
918
 
#ifdef WIN32
919
 
        LeaveCriticalSection(&sysfileSection);
920
 
#endif
921
 
 
922
926
        /* can't use ereport here because of possible recursion */
923
927
        if (rc != count)
924
928
                write_stderr("could not write to log file: %s\n", strerror(errno));
942
946
        for (;;)
943
947
        {
944
948
                DWORD           bytesRead;
945
 
 
946
 
                if (!ReadFile(syslogPipe[0],
947
 
                                          logbuffer + bytes_in_logbuffer,
948
 
                                          sizeof(logbuffer) - bytes_in_logbuffer,
949
 
                                          &bytesRead, 0))
 
949
                BOOL            result;
 
950
 
 
951
                result = ReadFile(syslogPipe[0],
 
952
                                                  logbuffer + bytes_in_logbuffer,
 
953
                                                  sizeof(logbuffer) - bytes_in_logbuffer,
 
954
                                                  &bytesRead, 0);
 
955
 
 
956
                /*
 
957
                 * Enter critical section before doing anything that might touch
 
958
                 * global state shared by the main thread. Anything that uses
 
959
                 * palloc()/pfree() in particular are not safe outside the critical
 
960
                 * section.
 
961
                 */
 
962
                EnterCriticalSection(&sysloggerSection);
 
963
                if (!result)
950
964
                {
951
965
                        DWORD           error = GetLastError();
952
966
 
963
977
                        bytes_in_logbuffer += bytesRead;
964
978
                        process_pipe_input(logbuffer, &bytes_in_logbuffer);
965
979
                }
 
980
                LeaveCriticalSection(&sysloggerSection);
966
981
        }
967
982
 
968
983
        /* We exit the above loop only upon detecting pipe EOF */
971
986
        /* if there's any data left then force it out now */
972
987
        flush_pipe_input(logbuffer, &bytes_in_logbuffer);
973
988
 
 
989
        LeaveCriticalSection(&sysloggerSection);
974
990
        _endthread();
975
991
        return 0;
976
992
}
1094
1110
                _setmode(_fileno(fh), _O_TEXT); /* use CRLF line endings on Windows */
1095
1111
#endif
1096
1112
 
1097
 
                /* On Windows, need to interlock against data-transfer thread */
1098
 
#ifdef WIN32
1099
 
                EnterCriticalSection(&sysfileSection);
1100
 
#endif
1101
 
 
1102
1113
                fclose(syslogFile);
1103
1114
                syslogFile = fh;
1104
1115
 
1105
 
#ifdef WIN32
1106
 
                LeaveCriticalSection(&sysfileSection);
1107
 
#endif
1108
 
 
1109
1116
                /* instead of pfree'ing filename, remember it for next time */
1110
1117
                if (last_file_name != NULL)
1111
1118
                        pfree(last_file_name);
1161
1168
                _setmode(_fileno(fh), _O_TEXT); /* use CRLF line endings on Windows */
1162
1169
#endif
1163
1170
 
1164
 
                /* On Windows, need to interlock against data-transfer thread */
1165
 
#ifdef WIN32
1166
 
                EnterCriticalSection(&sysfileSection);
1167
 
#endif
1168
 
 
1169
1171
                fclose(csvlogFile);
1170
1172
                csvlogFile = fh;
1171
1173
 
1172
 
#ifdef WIN32
1173
 
                LeaveCriticalSection(&sysfileSection);
1174
 
#endif
1175
 
 
1176
1174
                /* instead of pfree'ing filename, remember it for next time */
1177
1175
                if (last_csv_file_name != NULL)
1178
1176
                        pfree(last_csv_file_name);