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

« back to all changes in this revision

Viewing changes to src/backend/utils/hash/dynahash.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:
63
63
 
64
64
#include "postgres.h"
65
65
 
 
66
#include <limits.h>
 
67
 
66
68
#include "access/xact.h"
67
69
#include "storage/shmem.h"
68
70
#include "storage/spin.h"
200
202
static int      choose_nelem_alloc(Size entrysize);
201
203
static bool init_htab(HTAB *hashp, long nelem);
202
204
static void hash_corrupted(HTAB *hashp);
 
205
static long next_pow2_long(long num);
 
206
static int      next_pow2_int(long num);
203
207
static void register_seq_scan(HTAB *hashp);
204
208
static void deregister_seq_scan(HTAB *hashp);
205
209
static bool has_seq_scans(HTAB *hashp);
374
378
        {
375
379
                /* Doesn't make sense to partition a local hash table */
376
380
                Assert(flags & HASH_SHARED_MEM);
377
 
                /* # of partitions had better be a power of 2 */
378
 
                Assert(info->num_partitions == (1L << my_log2(info->num_partitions)));
 
381
 
 
382
                /*
 
383
                 * The number of partitions had better be a power of 2. Also, it must
 
384
                 * be less than INT_MAX (see init_htab()), so call the int version of
 
385
                 * next_pow2.
 
386
                 */
 
387
                Assert(info->num_partitions == next_pow2_int(info->num_partitions));
379
388
 
380
389
                hctl->num_partitions = info->num_partitions;
381
390
        }
518
527
{
519
528
        HASHHDR    *hctl = hashp->hctl;
520
529
        HASHSEGMENT *segp;
521
 
        long            lnbuckets;
522
530
        int                     nbuckets;
523
531
        int                     nsegs;
524
532
 
533
541
         * number of buckets.  Allocate space for the next greater power of two
534
542
         * number of buckets
535
543
         */
536
 
        lnbuckets = (nelem - 1) / hctl->ffactor + 1;
537
 
 
538
 
        nbuckets = 1 << my_log2(lnbuckets);
 
544
        nbuckets = next_pow2_int((nelem - 1) / hctl->ffactor + 1);
539
545
 
540
546
        /*
541
547
         * In a partitioned table, nbuckets must be at least equal to
553
559
         * Figure number of directory segments needed, round up to a power of 2
554
560
         */
555
561
        nsegs = (nbuckets - 1) / hctl->ssize + 1;
556
 
        nsegs = 1 << my_log2(nsegs);
 
562
        nsegs = next_pow2_int(nsegs);
557
563
 
558
564
        /*
559
565
         * Make sure directory is big enough. If pre-allocated directory is too
623
629
                                elementAllocCnt;
624
630
 
625
631
        /* estimate number of buckets wanted */
626
 
        nBuckets = 1L << my_log2((num_entries - 1) / DEF_FFACTOR + 1);
 
632
        nBuckets = next_pow2_long((num_entries - 1) / DEF_FFACTOR + 1);
627
633
        /* # of segments needed for nBuckets */
628
 
        nSegments = 1L << my_log2((nBuckets - 1) / DEF_SEGSIZE + 1);
 
634
        nSegments = next_pow2_long((nBuckets - 1) / DEF_SEGSIZE + 1);
629
635
        /* directory entries */
630
636
        nDirEntries = DEF_DIRSIZE;
631
637
        while (nDirEntries < nSegments)
666
672
                                nDirEntries;
667
673
 
668
674
        /* estimate number of buckets wanted */
669
 
        nBuckets = 1L << my_log2((num_entries - 1) / DEF_FFACTOR + 1);
 
675
        nBuckets = next_pow2_long((num_entries - 1) / DEF_FFACTOR + 1);
670
676
        /* # of segments needed for nBuckets */
671
 
        nSegments = 1L << my_log2((nBuckets - 1) / DEF_SEGSIZE + 1);
 
677
        nSegments = next_pow2_long((nBuckets - 1) / DEF_SEGSIZE + 1);
672
678
        /* directory entries */
673
679
        nDirEntries = DEF_DIRSIZE;
674
680
        while (nDirEntries < nSegments)
821
827
#endif
822
828
 
823
829
        /*
 
830
         * If inserting, check if it is time to split a bucket.
 
831
         *
 
832
         * NOTE: failure to expand table is not a fatal error, it just means we
 
833
         * have to run at higher fill factor than we wanted.  However, if we're
 
834
         * using the palloc allocator then it will throw error anyway on
 
835
         * out-of-memory, so we must do this before modifying the table.
 
836
         */
 
837
        if (action == HASH_ENTER || action == HASH_ENTER_NULL)
 
838
        {
 
839
                /*
 
840
                 * Can't split if running in partitioned mode, nor if frozen, nor if
 
841
                 * table is the subject of any active hash_seq_search scans.  Strange
 
842
                 * order of these tests is to try to check cheaper conditions first.
 
843
                 */
 
844
                if (!IS_PARTITIONED(hctl) && !hashp->frozen &&
 
845
                        hctl->nentries / (long) (hctl->max_bucket + 1) >= hctl->ffactor &&
 
846
                        !has_seq_scans(hashp))
 
847
                        (void) expand_table(hashp);
 
848
        }
 
849
 
 
850
        /*
824
851
         * Do the initial lookup
825
852
         */
826
853
        bucket = calc_bucket(hctl, hashvalue);
940
967
                        currBucket->hashvalue = hashvalue;
941
968
                        hashp->keycopy(ELEMENTKEY(currBucket), keyPtr, keysize);
942
969
 
943
 
                        /* caller is expected to fill the data field on return */
944
 
 
945
970
                        /*
946
 
                         * Check if it is time to split a bucket.  Can't split if running
947
 
                         * in partitioned mode, nor if table is the subject of any active
948
 
                         * hash_seq_search scans.  Strange order of these tests is to try
949
 
                         * to check cheaper conditions first.
 
971
                         * Caller is expected to fill the data field on return.  DO NOT
 
972
                         * insert any code that could possibly throw error here, as doing
 
973
                         * so would leave the table entry incomplete and hence corrupt the
 
974
                         * caller's data structure.
950
975
                         */
951
 
                        if (!IS_PARTITIONED(hctl) &&
952
 
                        hctl->nentries / (long) (hctl->max_bucket + 1) >= hctl->ffactor &&
953
 
                                !has_seq_scans(hashp))
954
 
                        {
955
 
                                /*
956
 
                                 * NOTE: failure to expand table is not a fatal error, it just
957
 
                                 * means we have to run at higher fill factor than we wanted.
958
 
                                 */
959
 
                                expand_table(hashp);
960
 
                        }
961
976
 
962
977
                        return (void *) ELEMENTKEY(currBucket);
963
978
        }
1394
1409
        int                     i;
1395
1410
        long            limit;
1396
1411
 
 
1412
        /* guard against too-large input, which would put us into infinite loop */
 
1413
        if (num > LONG_MAX / 2)
 
1414
                num = LONG_MAX / 2;
 
1415
 
1397
1416
        for (i = 0, limit = 1; limit < num; i++, limit <<= 1)
1398
1417
                ;
1399
1418
        return i;
1400
1419
}
1401
1420
 
 
1421
/* calculate first power of 2 >= num, bounded to what will fit in a long */
 
1422
static long
 
1423
next_pow2_long(long num)
 
1424
{
 
1425
        /* my_log2's internal range check is sufficient */
 
1426
        return 1L << my_log2(num);
 
1427
}
 
1428
 
 
1429
/* calculate first power of 2 >= num, bounded to what will fit in an int */
 
1430
static int
 
1431
next_pow2_int(long num)
 
1432
{
 
1433
        if (num > INT_MAX / 2)
 
1434
                num = INT_MAX / 2;
 
1435
        return 1 << my_log2(num);
 
1436
}
 
1437
 
1402
1438
 
1403
1439
/************************* SEQ SCAN TRACKING ************************/
1404
1440