~ubuntu-branches/ubuntu/vivid/postgresql-9.4/vivid-security

« back to all changes in this revision

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

  • Committer: Package Import Robot
  • Author(s): Martin Pitt
  • Date: 2015-10-08 15:36:31 UTC
  • mfrom: (1.2.3) (11.1.2 vivid-proposed)
  • Revision ID: package-import@ubuntu.com-20151008153631-dyiutwil2zjh9pxs
Tags: 9.4.5-0ubuntu0.15.04
* New upstream security/bug fix release: (LP: #1504132)
  - Guard against stack overflows in json parsing.
    If an application constructs PostgreSQL json or jsonb values from
    arbitrary user input, the application's users can reliably crash the
    PostgreSQL server, causing momentary denial of service.  (CVE-2015-5289)

  - Fix contrib/pgcrypto to detect and report too-short crypt() salts
    Certain invalid salt arguments crashed the server or disclosed a few
    bytes of server memory.  We have not ruled out the viability of attacks
    that arrange for presence of confidential information in the disclosed
    bytes, but they seem unlikely.  (CVE-2015-5288)

  - See release notes for details about other fixes.

Show diffs side-by-side

added added

removed removed

Lines of Context:
67
67
#include "getopt_long.h"
68
68
#include "miscadmin.h"
69
69
 
 
70
 
 
71
/* Define PG_FLUSH_DATA_WORKS if we have an implementation for pg_flush_data */
 
72
#if defined(HAVE_SYNC_FILE_RANGE)
 
73
#define PG_FLUSH_DATA_WORKS 1
 
74
#elif defined(USE_POSIX_FADVISE) && defined(POSIX_FADV_DONTNEED)
 
75
#define PG_FLUSH_DATA_WORKS 1
 
76
#endif
 
77
 
70
78
/* Ideally this would be in a .h file, but it hardly seems worth the trouble */
71
79
extern const char *select_default_timezone(const char *share_path);
72
80
 
218
226
#endif
219
227
static char **readfile(const char *path);
220
228
static void writefile(char *path, char **lines);
221
 
static void walkdir(char *path, void (*action) (char *fname, bool isdir));
222
 
static void walktblspc_links(char *path, void (*action) (char *fname, bool isdir));
223
 
static void pre_sync_fname(char *fname, bool isdir);
224
 
static void fsync_fname(char *fname, bool isdir);
 
229
static void walkdir(const char *path,
 
230
                void (*action) (const char *fname, bool isdir),
 
231
                bool process_symlinks);
 
232
#ifdef PG_FLUSH_DATA_WORKS
 
233
static void pre_sync_fname(const char *fname, bool isdir);
 
234
#endif
 
235
static void fsync_fname_ext(const char *fname, bool isdir);
225
236
static FILE *popen_check(const char *command, const char *mode);
226
237
static void exit_nicely(void);
227
238
static char *get_id(void);
249
260
static void vacuum_db(void);
250
261
static void make_template0(void);
251
262
static void make_postgres(void);
252
 
static void perform_fsync(void);
 
263
static void fsync_pgdata(void);
253
264
static void trapsig(int signum);
254
265
static void check_ok(void);
255
266
static char *escape_quotes(const char *src);
526
537
 * walkdir: recursively walk a directory, applying the action to each
527
538
 * regular file and directory (including the named directory itself).
528
539
 *
529
 
 * Adapted from copydir() in copydir.c.
 
540
 * If process_symlinks is true, the action and recursion are also applied
 
541
 * to regular files and directories that are pointed to by symlinks in the
 
542
 * given directory; otherwise symlinks are ignored.  Symlinks are always
 
543
 * ignored in subdirectories, ie we intentionally don't pass down the
 
544
 * process_symlinks flag to recursive calls.
 
545
 *
 
546
 * Errors are reported but not considered fatal.
 
547
 *
 
548
 * See also walkdir in fd.c, which is a backend version of this logic.
530
549
 */
531
550
static void
532
 
walkdir(char *path, void (*action) (char *fname, bool isdir))
 
551
walkdir(const char *path,
 
552
                void (*action) (const char *fname, bool isdir),
 
553
                bool process_symlinks)
533
554
{
534
555
        DIR                *dir;
535
 
        struct dirent *direntry;
536
 
        char            subpath[MAXPGPATH];
 
556
        struct dirent *de;
537
557
 
538
558
        dir = opendir(path);
539
559
        if (dir == NULL)
540
560
        {
541
561
                fprintf(stderr, _("%s: could not open directory \"%s\": %s\n"),
542
562
                                progname, path, strerror(errno));
543
 
                exit_nicely();
 
563
                return;
544
564
        }
545
565
 
546
 
        while (errno = 0, (direntry = readdir(dir)) != NULL)
 
566
        while (errno = 0, (de = readdir(dir)) != NULL)
547
567
        {
 
568
                char            subpath[MAXPGPATH];
548
569
                struct stat fst;
 
570
                int                     sret;
549
571
 
550
 
                if (strcmp(direntry->d_name, ".") == 0 ||
551
 
                        strcmp(direntry->d_name, "..") == 0)
 
572
                if (strcmp(de->d_name, ".") == 0 ||
 
573
                        strcmp(de->d_name, "..") == 0)
552
574
                        continue;
553
575
 
554
 
                snprintf(subpath, MAXPGPATH, "%s/%s", path, direntry->d_name);
555
 
 
556
 
                if (lstat(subpath, &fst) < 0)
 
576
                snprintf(subpath, MAXPGPATH, "%s/%s", path, de->d_name);
 
577
 
 
578
                if (process_symlinks)
 
579
                        sret = stat(subpath, &fst);
 
580
                else
 
581
                        sret = lstat(subpath, &fst);
 
582
 
 
583
                if (sret < 0)
557
584
                {
558
585
                        fprintf(stderr, _("%s: could not stat file \"%s\": %s\n"),
559
586
                                        progname, subpath, strerror(errno));
560
 
                        exit_nicely();
 
587
                        continue;
561
588
                }
562
589
 
563
 
                if (S_ISDIR(fst.st_mode))
564
 
                        walkdir(subpath, action);
565
 
                else if (S_ISREG(fst.st_mode))
 
590
                if (S_ISREG(fst.st_mode))
566
591
                        (*action) (subpath, false);
 
592
                else if (S_ISDIR(fst.st_mode))
 
593
                        walkdir(subpath, action, false);
567
594
        }
568
595
 
569
596
        if (errno)
570
 
        {
571
597
                fprintf(stderr, _("%s: could not read directory \"%s\": %s\n"),
572
598
                                progname, path, strerror(errno));
573
 
                exit_nicely();
574
 
        }
575
599
 
576
 
        if (closedir(dir))
577
 
        {
578
 
                fprintf(stderr, _("%s: could not close directory \"%s\": %s\n"),
579
 
                                progname, path, strerror(errno));
580
 
                exit_nicely();
581
 
        }
 
600
        (void) closedir(dir);
582
601
 
583
602
        /*
584
603
         * It's important to fsync the destination directory itself as individual
590
609
}
591
610
 
592
611
/*
593
 
 * walktblspc_links: call walkdir on each entry under the given
594
 
 * pg_tblspc directory, or do nothing if pg_tblspc doesn't exist.
595
 
 */
596
 
static void
597
 
walktblspc_links(char *path, void (*action) (char *fname, bool isdir))
598
 
{
599
 
        DIR                *dir;
600
 
        struct dirent *direntry;
601
 
        char            subpath[MAXPGPATH];
602
 
 
603
 
        dir = opendir(path);
604
 
        if (dir == NULL)
605
 
        {
606
 
                if (errno == ENOENT)
607
 
                        return;
608
 
                fprintf(stderr, _("%s: could not open directory \"%s\": %s\n"),
609
 
                                progname, path, strerror(errno));
610
 
                exit_nicely();
611
 
        }
612
 
 
613
 
        while (errno = 0, (direntry = readdir(dir)) != NULL)
614
 
        {
615
 
                if (strcmp(direntry->d_name, ".") == 0 ||
616
 
                        strcmp(direntry->d_name, "..") == 0)
617
 
                        continue;
618
 
 
619
 
                /* fsync the version specific tablespace subdirectory */
620
 
                snprintf(subpath, sizeof(subpath), "%s/%s/%s",
621
 
                                 path, direntry->d_name, TABLESPACE_VERSION_DIRECTORY);
622
 
 
623
 
                walkdir(subpath, action);
624
 
        }
625
 
 
626
 
        if (errno)
627
 
        {
628
 
                fprintf(stderr, _("%s: could not read directory \"%s\": %s\n"),
629
 
                                progname, path, strerror(errno));
630
 
                exit_nicely();
631
 
        }
632
 
 
633
 
        if (closedir(dir))
634
 
        {
635
 
                fprintf(stderr, _("%s: could not close directory \"%s\": %s\n"),
636
 
                                progname, path, strerror(errno));
637
 
                exit_nicely();
638
 
        }
639
 
}
640
 
 
641
 
/*
642
612
 * Hint to the OS that it should get ready to fsync() this file.
 
613
 *
 
614
 * Ignores errors trying to open unreadable files, and reports other errors
 
615
 * non-fatally.
643
616
 */
 
617
#ifdef PG_FLUSH_DATA_WORKS
 
618
 
644
619
static void
645
 
pre_sync_fname(char *fname, bool isdir)
 
620
pre_sync_fname(const char *fname, bool isdir)
646
621
{
647
 
#if defined(HAVE_SYNC_FILE_RANGE) || \
648
 
        (defined(USE_POSIX_FADVISE) && defined(POSIX_FADV_DONTNEED))
649
622
        int                     fd;
650
623
 
651
624
        fd = open(fname, O_RDONLY | PG_BINARY);
652
625
 
653
 
        /*
654
 
         * Some OSs don't allow us to open directories at all (Windows returns
655
 
         * EACCES)
656
 
         */
657
 
        if (fd < 0 && isdir && (errno == EISDIR || errno == EACCES))
658
 
                return;
659
 
 
660
626
        if (fd < 0)
661
627
        {
 
628
                if (errno == EACCES || (isdir && errno == EISDIR))
 
629
                        return;
662
630
                fprintf(stderr, _("%s: could not open file \"%s\": %s\n"),
663
631
                                progname, fname, strerror(errno));
664
 
                exit_nicely();
 
632
                return;
665
633
        }
666
634
 
667
635
        /*
668
 
         * Prefer sync_file_range, else use posix_fadvise.  We ignore any error
669
 
         * here since this operation is only a hint anyway.
 
636
         * We do what pg_flush_data() would do in the backend: prefer to use
 
637
         * sync_file_range, but fall back to posix_fadvise.  We ignore errors
 
638
         * because this is only a hint.
670
639
         */
671
640
#if defined(HAVE_SYNC_FILE_RANGE)
672
 
        sync_file_range(fd, 0, 0, SYNC_FILE_RANGE_WRITE);
 
641
        (void) sync_file_range(fd, 0, 0, SYNC_FILE_RANGE_WRITE);
673
642
#elif defined(USE_POSIX_FADVISE) && defined(POSIX_FADV_DONTNEED)
674
 
        posix_fadvise(fd, 0, 0, POSIX_FADV_DONTNEED);
 
643
        (void) posix_fadvise(fd, 0, 0, POSIX_FADV_DONTNEED);
 
644
#else
 
645
#error PG_FLUSH_DATA_WORKS should not have been defined
675
646
#endif
676
647
 
677
 
        close(fd);
678
 
#endif
 
648
        (void) close(fd);
679
649
}
680
650
 
 
651
#endif   /* PG_FLUSH_DATA_WORKS */
 
652
 
681
653
/*
682
 
 * fsync a file or directory
683
 
 *
684
 
 * Try to fsync directories but ignore errors that indicate the OS
685
 
 * just doesn't allow/require fsyncing directories.
686
 
 *
687
 
 * Adapted from fsync_fname() in copydir.c.
 
654
 * fsync_fname_ext -- Try to fsync a file or directory
 
655
 *
 
656
 * Ignores errors trying to open unreadable files, or trying to fsync
 
657
 * directories on systems where that isn't allowed/required.  Reports
 
658
 * other errors non-fatally.
688
659
 */
689
660
static void
690
 
fsync_fname(char *fname, bool isdir)
 
661
fsync_fname_ext(const char *fname, bool isdir)
691
662
{
692
663
        int                     fd;
 
664
        int                     flags;
693
665
        int                     returncode;
694
666
 
695
667
        /*
696
668
         * Some OSs require directories to be opened read-only whereas other
697
669
         * systems don't allow us to fsync files opened read-only; so we need both
698
 
         * cases here
 
670
         * cases here.  Using O_RDWR will cause us to fail to fsync files that are
 
671
         * not writable by our userid, but we assume that's OK.
699
672
         */
 
673
        flags = PG_BINARY;
700
674
        if (!isdir)
701
 
                fd = open(fname, O_RDWR | PG_BINARY);
 
675
                flags |= O_RDWR;
702
676
        else
703
 
                fd = open(fname, O_RDONLY | PG_BINARY);
 
677
                flags |= O_RDONLY;
704
678
 
705
679
        /*
706
 
         * Some OSs don't allow us to open directories at all (Windows returns
707
 
         * EACCES)
 
680
         * Open the file, silently ignoring errors about unreadable files (or
 
681
         * unsupported operations, e.g. opening a directory under Windows), and
 
682
         * logging others.
708
683
         */
709
 
        if (fd < 0 && isdir && (errno == EISDIR || errno == EACCES))
710
 
                return;
711
 
 
712
 
        else if (fd < 0)
 
684
        fd = open(fname, flags);
 
685
        if (fd < 0)
713
686
        {
 
687
                if (errno == EACCES || (isdir && errno == EISDIR))
 
688
                        return;
714
689
                fprintf(stderr, _("%s: could not open file \"%s\": %s\n"),
715
690
                                progname, fname, strerror(errno));
716
 
                exit_nicely();
 
691
                return;
717
692
        }
718
693
 
719
694
        returncode = fsync(fd);
720
695
 
721
 
        /* Some OSs don't allow us to fsync directories at all */
722
 
        if (returncode != 0 && isdir && errno == EBADF)
723
 
        {
724
 
                close(fd);
725
 
                return;
726
 
        }
727
 
 
728
 
        if (returncode != 0)
729
 
        {
 
696
        /*
 
697
         * Some OSes don't allow us to fsync directories at all, so we can ignore
 
698
         * those errors. Anything else needs to be reported.
 
699
         */
 
700
        if (returncode != 0 && !(isdir && errno == EBADF))
730
701
                fprintf(stderr, _("%s: could not fsync file \"%s\": %s\n"),
731
702
                                progname, fname, strerror(errno));
732
 
                exit_nicely();
733
 
        }
734
703
 
735
 
        close(fd);
 
704
        (void) close(fd);
736
705
}
737
706
 
738
707
/*
2424
2393
}
2425
2394
 
2426
2395
/*
2427
 
 * fsync everything down to disk
 
2396
 * Issue fsync recursively on PGDATA and all its contents.
 
2397
 *
 
2398
 * We fsync regular files and directories wherever they are, but we
 
2399
 * follow symlinks only for pg_xlog and immediately under pg_tblspc.
 
2400
 * Other symlinks are presumed to point at files we're not responsible
 
2401
 * for fsyncing, and might not have privileges to write at all.
 
2402
 *
 
2403
 * Errors are reported but not considered fatal.
2428
2404
 */
2429
2405
static void
2430
 
perform_fsync(void)
 
2406
fsync_pgdata(void)
2431
2407
{
2432
 
        char            pdir[MAXPGPATH];
 
2408
        bool            xlog_is_symlink;
 
2409
        char            pg_xlog[MAXPGPATH];
2433
2410
        char            pg_tblspc[MAXPGPATH];
2434
2411
 
2435
2412
        fputs(_("syncing data to disk ... "), stdout);
2436
2413
        fflush(stdout);
2437
2414
 
2438
 
        /*
2439
 
         * We need to name the parent of PGDATA.  get_parent_directory() isn't
2440
 
         * enough here, because it can result in an empty string.
2441
 
         */
2442
 
        snprintf(pdir, MAXPGPATH, "%s/..", pg_data);
2443
 
        canonicalize_path(pdir);
2444
 
 
2445
 
        /*
2446
 
         * Hint to the OS so that we're going to fsync each of these files soon.
2447
 
         */
2448
 
 
2449
 
        /* first the parent of the PGDATA directory */
2450
 
        pre_sync_fname(pdir, true);
2451
 
 
2452
 
        /* then recursively through the data directory */
2453
 
        walkdir(pg_data, pre_sync_fname);
2454
 
 
2455
 
        /* now do the same thing for everything under pg_tblspc */
 
2415
        snprintf(pg_xlog, MAXPGPATH, "%s/pg_xlog", pg_data);
2456
2416
        snprintf(pg_tblspc, MAXPGPATH, "%s/pg_tblspc", pg_data);
2457
 
        walktblspc_links(pg_tblspc, pre_sync_fname);
2458
 
 
2459
 
        /*
2460
 
         * Now, do the fsync()s in the same order.
2461
 
         */
2462
 
 
2463
 
        /* first the parent of the PGDATA directory */
2464
 
        fsync_fname(pdir, true);
2465
 
 
2466
 
        /* then recursively through the data directory */
2467
 
        walkdir(pg_data, fsync_fname);
2468
 
 
2469
 
        /* and now the same for all tablespaces */
2470
 
        walktblspc_links(pg_tblspc, fsync_fname);
 
2417
 
 
2418
        /*
 
2419
         * If pg_xlog is a symlink, we'll need to recurse into it separately,
 
2420
         * because the first walkdir below will ignore it.
 
2421
         */
 
2422
        xlog_is_symlink = false;
 
2423
 
 
2424
#ifndef WIN32
 
2425
        {
 
2426
                struct stat st;
 
2427
 
 
2428
                if (lstat(pg_xlog, &st) < 0)
 
2429
                        fprintf(stderr, _("%s: could not stat file \"%s\": %s\n"),
 
2430
                                        progname, pg_xlog, strerror(errno));
 
2431
                else if (S_ISLNK(st.st_mode))
 
2432
                        xlog_is_symlink = true;
 
2433
        }
 
2434
#else
 
2435
        if (pgwin32_is_junction(pg_xlog))
 
2436
                xlog_is_symlink = true;
 
2437
#endif
 
2438
 
 
2439
        /*
 
2440
         * If possible, hint to the kernel that we're soon going to fsync the data
 
2441
         * directory and its contents.
 
2442
         */
 
2443
#ifdef PG_FLUSH_DATA_WORKS
 
2444
        walkdir(pg_data, pre_sync_fname, false);
 
2445
        if (xlog_is_symlink)
 
2446
                walkdir(pg_xlog, pre_sync_fname, false);
 
2447
        walkdir(pg_tblspc, pre_sync_fname, true);
 
2448
#endif
 
2449
 
 
2450
        /*
 
2451
         * Now we do the fsync()s in the same order.
 
2452
         *
 
2453
         * The main call ignores symlinks, so in addition to specially processing
 
2454
         * pg_xlog if it's a symlink, pg_tblspc has to be visited separately with
 
2455
         * process_symlinks = true.  Note that if there are any plain directories
 
2456
         * in pg_tblspc, they'll get fsync'd twice.  That's not an expected case
 
2457
         * so we don't worry about optimizing it.
 
2458
         */
 
2459
        walkdir(pg_data, fsync_fname_ext, false);
 
2460
        if (xlog_is_symlink)
 
2461
                walkdir(pg_xlog, fsync_fname_ext, false);
 
2462
        walkdir(pg_tblspc, fsync_fname_ext, true);
2471
2463
 
2472
2464
        check_ok();
2473
2465
}
3734
3726
                exit(1);
3735
3727
        }
3736
3728
 
3737
 
        /* If we only need to fsync, just to it and exit */
 
3729
        /* If we only need to fsync, just do it and exit */
3738
3730
        if (sync_only)
3739
3731
        {
3740
3732
                setup_pgdata();
3741
 
                perform_fsync();
 
3733
 
 
3734
                /* must check that directory is readable */
 
3735
                if (pg_check_dir(pg_data) <= 0)
 
3736
                {
 
3737
                        fprintf(stderr, _("%s: could not access directory \"%s\": %s\n"),
 
3738
                                        progname, pg_data, strerror(errno));
 
3739
                        exit_nicely();
 
3740
                }
 
3741
 
 
3742
                fsync_pgdata();
3742
3743
                return 0;
3743
3744
        }
3744
3745
 
3791
3792
        initialize_data_directory();
3792
3793
 
3793
3794
        if (do_sync)
3794
 
                perform_fsync();
 
3795
                fsync_pgdata();
3795
3796
        else
3796
3797
                printf(_("\nSync to disk skipped.\nThe data directory might become corrupt if the operating system crashes.\n"));
3797
3798