~ubuntu-branches/ubuntu/trusty/postgresql-9.3/trusty-security

« back to all changes in this revision

Viewing changes to src/bin/pg_dump/pg_backup_tar.c

  • Committer: Package Import Robot
  • Author(s): Martin Pitt
  • Date: 2016-02-11 15:44:43 UTC
  • mfrom: (1.2.4)
  • Revision ID: package-import@ubuntu.com-20160211154443-hmgw1nqsuckp5pa9
Tags: 9.3.11-0ubuntu0.14.04
* New upstream security/bug fix release: (LP: #1544576)
  - Fix infinite loops and buffer-overrun problems in regular expressions.
    Very large character ranges in bracket expressions could cause infinite
    loops in some cases, and memory overwrites in other cases.
    (CVE-2016-0773)
  - Prevent certain PL/Java parameters from being set by non-superusers.
    This change mitigates a PL/Java security bug (CVE-2016-0766), which was
    fixed in PL/Java by marking these parameters as superuser-only. To fix
    the security hazard for sites that update PostgreSQL more frequently
    than PL/Java, make the core code aware of them also.
  - See release notes for details about other fixes.

Show diffs side-by-side

added added

removed removed

Lines of Context:
79
79
        ArchiveHandle *AH;
80
80
} TAR_MEMBER;
81
81
 
82
 
/*
83
 
 * Maximum file size for a tar member: The limit inherent in the
84
 
 * format is 2^33-1 bytes (nearly 8 GB).  But we don't want to exceed
85
 
 * what we can represent in pgoff_t.
86
 
 */
87
 
#define MAX_TAR_MEMBER_FILELEN (((int64) 1 << Min(33, sizeof(pgoff_t)*8 - 1)) - 1)
88
 
 
89
82
typedef struct
90
83
{
91
84
        int                     hasSeek;
1036
1029
        int                     sum;
1037
1030
        int                     chk = tarChecksum(header);
1038
1031
 
1039
 
        sscanf(&header[148], "%8o", &sum);
 
1032
        sum = read_tar_number(&header[148], 8);
1040
1033
 
1041
1034
        if (sum != chk)
1042
1035
                return false;
1075
1068
        th->fileLen = ftello(tmp);
1076
1069
        fseeko(tmp, 0, SEEK_SET);
1077
1070
 
1078
 
        /*
1079
 
         * Some compilers will throw a warning knowing this test can never be true
1080
 
         * because pgoff_t can't exceed the compared maximum on their platform.
1081
 
         */
1082
 
        if (th->fileLen > MAX_TAR_MEMBER_FILELEN)
1083
 
                exit_horribly(modulename, "archive member too large for tar format\n");
1084
 
 
1085
1071
        _tarWriteHeader(th);
1086
1072
 
1087
1073
        while ((cnt = fread(buf, 1, sizeof(buf), tmp)) > 0)
1207
1193
{
1208
1194
        lclContext *ctx = (lclContext *) AH->formatData;
1209
1195
        char            h[512];
1210
 
        char            tag[100];
 
1196
        char            tag[100 + 1];
1211
1197
        int                     sum,
1212
1198
                                chk;
1213
 
        size_t          len;
1214
 
        unsigned long ullen;
 
1199
        pgoff_t         len;
1215
1200
        pgoff_t         hPos;
1216
1201
        bool            gotBlock = false;
1217
1202
 
1248
1233
 
1249
1234
                /* Calc checksum */
1250
1235
                chk = tarChecksum(h);
1251
 
                sscanf(&h[148], "%8o", &sum);
 
1236
                sum = read_tar_number(&h[148], 8);
1252
1237
 
1253
1238
                /*
1254
1239
                 * If the checksum failed, see if it is a null block. If so, silently
1271
1256
                }
1272
1257
        }
1273
1258
 
1274
 
        sscanf(&h[0], "%99s", tag);
1275
 
        sscanf(&h[124], "%12lo", &ullen);
1276
 
        len = (size_t) ullen;
 
1259
        /* Name field is 100 bytes, might not be null-terminated */
 
1260
        strlcpy(tag, &h[0], 100 + 1);
 
1261
 
 
1262
        len = read_tar_number(&h[124], 12);
1277
1263
 
1278
1264
        {
1279
 
                char            buf[100];
 
1265
                char            posbuf[32];
 
1266
                char            lenbuf[32];
1280
1267
 
1281
 
                snprintf(buf, sizeof(buf), INT64_FORMAT, (int64) hPos);
1282
 
                ahlog(AH, 3, "TOC Entry %s at %s (length %lu, checksum %d)\n",
1283
 
                          tag, buf, (unsigned long) len, sum);
 
1268
                snprintf(posbuf, sizeof(posbuf), UINT64_FORMAT, (uint64) hPos);
 
1269
                snprintf(lenbuf, sizeof(lenbuf), UINT64_FORMAT, (uint64) len);
 
1270
                ahlog(AH, 3, "TOC Entry %s at %s (length %s, checksum %d)\n",
 
1271
                          tag, posbuf, lenbuf, sum);
1284
1272
        }
1285
1273
 
1286
1274
        if (chk != sum)
1287
1275
        {
1288
 
                char            buf[100];
 
1276
                char            posbuf[32];
1289
1277
 
1290
 
                snprintf(buf, sizeof(buf), INT64_FORMAT, (int64) ftello(ctx->tarFH));
 
1278
                snprintf(posbuf, sizeof(posbuf), UINT64_FORMAT,
 
1279
                                 (uint64) ftello(ctx->tarFH));
1291
1280
                exit_horribly(modulename,
1292
1281
                                          "corrupt tar header found in %s "
1293
1282
                                          "(expected %d, computed %d) file position %s\n",
1294
 
                                          tag, sum, chk, buf);
 
1283
                                          tag, sum, chk, posbuf);
1295
1284
        }
1296
1285
 
1297
1286
        th->targetFile = pg_strdup(tag);
1306
1295
{
1307
1296
        char            h[512];
1308
1297
 
1309
 
        tarCreateHeader(h, th->targetFile, NULL, th->fileLen, 0600, 04000, 02000, time(NULL));
 
1298
        tarCreateHeader(h, th->targetFile, NULL, th->fileLen,
 
1299
                                        0600, 04000, 02000, time(NULL));
1310
1300
 
1311
1301
        /* Now write the completed header. */
1312
1302
        if (fwrite(h, 1, 512, th->tarFH) != 512)