~ubuntu-branches/ubuntu/oneiric/postgresql-9.1/oneiric-security

« back to all changes in this revision

Viewing changes to src/bin/pg_ctl/pg_ctl.c

  • Committer: Package Import Robot
  • Author(s): Martin Pitt
  • Date: 2013-02-05 18:13:52 UTC
  • mfrom: (1.1.10) (10.1.5 oneiric-proposed)
  • Revision ID: package-import@ubuntu.com-20130205181352-3kw4f94ilqklzm7c
Tags: 9.1.8-0ubuntu11.10
* New upstream security/bug fix release: (LP: #1116336)
  - Prevent execution of enum_recv from SQL
    The function was misdeclared, allowing a simple SQL command to crash the
    server.  In principle an attacker might be able to use it to examine the
    contents of server memory.  Our thanks to Sumit Soni (via Secunia SVCRP)
    for reporting this issue. (CVE-2013-0255)
  - See HISTORY/changelog.gz for the other bug fixes.

Show diffs side-by-side

added added

removed removed

Lines of Context:
20
20
#include "postgres_fe.h"
21
21
#include "libpq-fe.h"
22
22
 
 
23
#include <fcntl.h>
23
24
#include <locale.h>
24
25
#include <signal.h>
25
26
#include <time.h>
305
306
static char **
306
307
readfile(const char *path)
307
308
{
308
 
        FILE       *infile;
309
 
        int                     maxlength = 1,
310
 
                                linelen = 0;
311
 
        int                     nlines = 0;
 
309
        int                     fd;
 
310
        int                     nlines;
312
311
        char      **result;
313
312
        char       *buffer;
314
 
        int                     c;
315
 
 
316
 
        if ((infile = fopen(path, "r")) == NULL)
317
 
                return NULL;
318
 
 
319
 
        /* pass over the file twice - the first time to size the result */
320
 
 
321
 
        while ((c = fgetc(infile)) != EOF)
322
 
        {
323
 
                linelen++;
324
 
                if (c == '\n')
325
 
                {
 
313
        char       *linebegin;
 
314
        int                     i;
 
315
        int                     n;
 
316
        int                     len;
 
317
        struct stat     statbuf;
 
318
 
 
319
        /*
 
320
         * Slurp the file into memory.
 
321
         *
 
322
         * The file can change concurrently, so we read the whole file into memory
 
323
         * with a single read() call. That's not guaranteed to get an atomic
 
324
         * snapshot, but in practice, for a small file, it's close enough for the
 
325
         * current use.
 
326
         */
 
327
        fd = open(path, O_RDONLY | PG_BINARY, 0);
 
328
        if (fd < 0)
 
329
                return NULL;
 
330
        if (fstat(fd, &statbuf) < 0)
 
331
        {
 
332
                close(fd);
 
333
                return NULL;
 
334
        }
 
335
        if (statbuf.st_size == 0)
 
336
        {
 
337
                /* empty file */
 
338
                close(fd);
 
339
                result = (char **) pg_malloc(sizeof(char *));
 
340
                *result = NULL;
 
341
                return result;
 
342
        }
 
343
        buffer = pg_malloc(statbuf.st_size + 1);
 
344
 
 
345
        len = read(fd, buffer, statbuf.st_size + 1);
 
346
        close(fd);
 
347
        if (len != statbuf.st_size)
 
348
        {
 
349
                /* oops, the file size changed between fstat and read */
 
350
                free(buffer);
 
351
                return NULL;
 
352
        }
 
353
 
 
354
        /*
 
355
         * Count newlines. We expect there to be a newline after each full line,
 
356
         * including one at the end of file. If there isn't a newline at the end,
 
357
         * any characters after the last newline will be ignored.
 
358
         */
 
359
        nlines = 0;
 
360
        for (i = 0; i < len; i++)
 
361
        {
 
362
                if (buffer[i] == '\n')
326
363
                        nlines++;
327
 
                        if (linelen > maxlength)
328
 
                                maxlength = linelen;
329
 
                        linelen = 0;
330
 
                }
331
364
        }
332
365
 
333
 
        /* handle last line without a terminating newline (yuck) */
334
 
        if (linelen)
335
 
                nlines++;
336
 
        if (linelen > maxlength)
337
 
                maxlength = linelen;
338
 
 
339
 
        /* set up the result and the line buffer */
 
366
        /* set up the result buffer */
340
367
        result = (char **) pg_malloc((nlines + 1) * sizeof(char *));
341
 
        buffer = (char *) pg_malloc(maxlength + 1);
342
 
 
343
 
        /* now reprocess the file and store the lines */
344
 
        rewind(infile);
345
 
        nlines = 0;
346
 
        while (fgets(buffer, maxlength + 1, infile) != NULL)
347
 
                result[nlines++] = xstrdup(buffer);
348
 
 
349
 
        fclose(infile);
 
368
 
 
369
        /* now split the buffer into lines */
 
370
        linebegin = buffer;
 
371
        n = 0;
 
372
        for (i = 0; i < len; i++)
 
373
        {
 
374
                if (buffer[i] == '\n')
 
375
                {
 
376
                        int             slen = &buffer[i] - linebegin + 1;
 
377
                        char   *linebuf = pg_malloc(slen + 1);
 
378
                        memcpy(linebuf, linebegin, slen);
 
379
                        linebuf[slen] = '\0';
 
380
                        result[n++] = linebuf;
 
381
                        linebegin = &buffer[i + 1];
 
382
                }
 
383
        }
 
384
        result[n] = NULL;
 
385
 
350
386
        free(buffer);
351
 
        result[nlines] = NULL;
352
387
 
353
388
        return result;
354
389
}