23 changes: 13 additions & 10 deletions src/backend/utils/adt/txid.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,9 @@
#include "funcapi.h"
#include "miscadmin.h"
#include "libpq/pqformat.h"
#include "postmaster/postmaster.h"
#include "utils/builtins.h"
#include "utils/memutils.h"
#include "utils/snapmgr.h"


Expand Down Expand Up @@ -66,6 +68,8 @@ typedef struct

#define TXID_SNAPSHOT_SIZE(nxip) \
(offsetof(TxidSnapshot, xip) + sizeof(txid) * (nxip))
#define TXID_SNAPSHOT_MAX_NXIP \
((MaxAllocSize - offsetof(TxidSnapshot, xip)) / sizeof(txid))

/*
* Epoch values from xact.c
Expand Down Expand Up @@ -368,6 +372,13 @@ txid_current_snapshot(PG_FUNCTION_ARGS)

load_xid_epoch(&state);

/*
* Compile-time limits on the procarray (MAX_BACKENDS processes plus
* MAX_BACKENDS prepared transactions) guarantee nxip won't be too large.
*/
StaticAssertStmt(MAX_BACKENDS * 2 <= TXID_SNAPSHOT_MAX_NXIP,
"possible overflow in txid_current_snapshot()");

/* allocate */
nxip = cur->xcnt;
size = TXID_SNAPSHOT_SIZE(nxip);
Expand Down Expand Up @@ -445,20 +456,12 @@ txid_snapshot_recv(PG_FUNCTION_ARGS)
txid last = 0;
int nxip;
int i;
int avail;
int expect;
txid xmin,
xmax;

/*
* load nxip and check for nonsense.
*
* (nxip > avail) check is against int overflows in 'expect'.
*/
/* load and validate nxip */
nxip = pq_getmsgint(buf, 4);
avail = buf->len - buf->cursor;
expect = 8 + 8 + nxip * 8;
if (nxip < 0 || nxip > avail || expect > avail)
if (nxip < 0 || nxip > TXID_SNAPSHOT_MAX_NXIP)
goto bad_format;

xmin = pq_getmsgint64(buf);
Expand Down
32 changes: 30 additions & 2 deletions src/backend/utils/adt/varbit.c
Original file line number Diff line number Diff line change
Expand Up @@ -148,12 +148,22 @@ bit_in(PG_FUNCTION_ARGS)
sp = input_string;
}

/*
* Determine bitlength from input string. MaxAllocSize ensures a regular
* input is small enough, but we must check hex input.
*/
slen = strlen(sp);
/* Determine bitlength from input string */
if (bit_not_hex)
bitlen = slen;
else
{
if (slen > VARBITMAXLEN / 4)
ereport(ERROR,
(errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
errmsg("bit string length exceeds the maximum allowed (%d)",
VARBITMAXLEN)));
bitlen = slen * 4;
}

/*
* Sometimes atttypmod is not supplied. If it is supplied we need to make
Expand Down Expand Up @@ -450,12 +460,22 @@ varbit_in(PG_FUNCTION_ARGS)
sp = input_string;
}

/*
* Determine bitlength from input string. MaxAllocSize ensures a regular
* input is small enough, but we must check hex input.
*/
slen = strlen(sp);
/* Determine bitlength from input string */
if (bit_not_hex)
bitlen = slen;
else
{
if (slen > VARBITMAXLEN / 4)
ereport(ERROR,
(errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
errmsg("bit string length exceeds the maximum allowed (%d)",
VARBITMAXLEN)));
bitlen = slen * 4;
}

/*
* Sometimes atttypmod is not supplied. If it is supplied we need to make
Expand Down Expand Up @@ -535,6 +555,9 @@ varbit_in(PG_FUNCTION_ARGS)
/*
* varbit_out -
* Prints the string as bits to preserve length accurately
*
* XXX varbit_recv() and hex input to varbit_in() can load a value that this
* cannot emit. Consider using hex output for such values.
*/
Datum
varbit_out(PG_FUNCTION_ARGS)
Expand Down Expand Up @@ -944,6 +967,11 @@ bit_catenate(VarBit *arg1, VarBit *arg2)
bitlen1 = VARBITLEN(arg1);
bitlen2 = VARBITLEN(arg2);

if (bitlen1 > VARBITMAXLEN - bitlen2)
ereport(ERROR,
(errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
errmsg("bit string length exceeds the maximum allowed (%d)",
VARBITMAXLEN)));
bytelen = VARBITTOTALLEN(bitlen1 + bitlen2);

result = (VarBit *) palloc(bytelen);
Expand Down
3 changes: 3 additions & 0 deletions src/include/tsearch/ts_type.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#define _PG_TSTYPE_H_

#include "fmgr.h"
#include "utils/memutils.h"
#include "utils/pg_crc.h"


Expand Down Expand Up @@ -244,6 +245,8 @@ typedef TSQueryData *TSQuery;
* QueryItems, and lenofoperand is the total length of all operands
*/
#define COMPUTESIZE(size, lenofoperand) ( HDRSIZETQ + (size) * sizeof(QueryItem) + (lenofoperand) )
#define TSQUERY_TOO_BIG(size, lenofoperand) \
((size) > (MaxAllocSize - HDRSIZETQ - (lenofoperand)) / sizeof(QueryItem))

/* Returns a pointer to the first QueryItem in a TSQuery */
#define GETQUERY(x) ((QueryItem*)( (char*)(x)+HDRSIZETQ ))
Expand Down
7 changes: 7 additions & 0 deletions src/include/utils/varbit.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
#ifndef VARBIT_H
#define VARBIT_H

#include <limits.h>

#include "fmgr.h"

/*
Expand Down Expand Up @@ -53,6 +55,11 @@ typedef struct
/* Number of bytes needed to store a bit string of a given length */
#define VARBITTOTALLEN(BITLEN) (((BITLEN) + BITS_PER_BYTE-1)/BITS_PER_BYTE + \
VARHDRSZ + VARBITHDRSZ)
/*
* Maximum number of bits. Several code sites assume no overflow from
* computing bitlen + X; VARBITTOTALLEN() has the largest such X.
*/
#define VARBITMAXLEN (INT_MAX - BITS_PER_BYTE + 1)
/* pointer beyond the end of the bit string (like end() in STL containers) */
#define VARBITEND(PTR) (((bits8 *) (PTR)) + VARSIZE(PTR))
/* Mask that will cover exactly one byte, i.e. BITS_PER_BYTE bits */
Expand Down