summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKang Kai <kai.kang@windriver.com>2014-10-29 08:30:52 +0800
committerMartin Jansa <Martin.Jansa@gmail.com>2014-11-07 15:05:45 +0100
commitcd4cd791999f9684c1b9b50d4ce600d9e8dd423d (patch)
tree67b6ad191e063703bd2daab33b243365990462a9
parent3692902448c29828ce7d25d553a4e6bf11cbb9ec (diff)
downloadmeta-openembedded-cd4cd791999f9684c1b9b50d4ce600d9e8dd423d.tar.gz
postgresql: add fix for CVE-2014-0064 Security Advisory
Multiple integer overflows in the path_in and other unspecified functions in PostgreSQL before 8.4.20, 9.0.x before 9.0.16, 9.1.x before 9.1.12, 9.2.x before 9.2.7, and 9.3.x before 9.3.3 allow remote authenticated users to have unspecified impact and attack vectors, which trigger a buffer overflow. NOTE: this identifier has been SPLIT due to different affected versions; use CVE-2014-2669 for the hstore vector. http://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2014-0064 Signed-off-by: Yue Tao <Yue.Tao@windriver.com> Signed-off-by: Kai Kang <kai.kang@windriver.com> Signed-off-by: Martin Jansa <Martin.Jansa@gmail.com>
-rw-r--r--meta-oe/recipes-support/postgresql/files/0002-Predict-integer-overflow-to-avoid-buffer-overruns.patch605
-rw-r--r--meta-oe/recipes-support/postgresql/postgresql.inc5
2 files changed, 608 insertions, 2 deletions
diff --git a/meta-oe/recipes-support/postgresql/files/0002-Predict-integer-overflow-to-avoid-buffer-overruns.patch b/meta-oe/recipes-support/postgresql/files/0002-Predict-integer-overflow-to-avoid-buffer-overruns.patch
new file mode 100644
index 000000000..c8b4c80aa
--- /dev/null
+++ b/meta-oe/recipes-support/postgresql/files/0002-Predict-integer-overflow-to-avoid-buffer-overruns.patch
@@ -0,0 +1,605 @@
1From 12bbce15d93d7692ddff1405aa04b67f8a327f57 Mon Sep 17 00:00:00 2001
2From: Noah Misch <noah@leadboat.com>
3Date: Mon, 17 Feb 2014 09:33:31 -0500
4Subject: [PATCH] Predict integer overflow to avoid buffer overruns.
5
6commit 12bbce15d93d7692ddff1405aa04b67f8a327f57 REL9_2_STABLE
7
8Several functions, mostly type input functions, calculated an allocation
9size such that the calculation wrapped to a small positive value when
10arguments implied a sufficiently-large requirement. Writes past the end
11of the inadvertent small allocation followed shortly thereafter.
12Coverity identified the path_in() vulnerability; code inspection led to
13the rest. In passing, add check_stack_depth() to prevent stack overflow
14in related functions.
15
16Back-patch to 8.4 (all supported versions). The non-comment hstore
17changes touch code that did not exist in 8.4, so that part stops at 9.0.
18
19Noah Misch and Heikki Linnakangas, reviewed by Tom Lane.
20
21Security: CVE-2014-0064
22
23Upstream-Status: Backport
24
25Signed-off-by: Kai Kang <kai.kang@windriver.com>
26---
27 contrib/hstore/hstore.h | 15 ++++++++++++---
28 contrib/hstore/hstore_io.c | 21 +++++++++++++++++++++
29 contrib/hstore/hstore_op.c | 15 +++++++++++++++
30 contrib/intarray/_int.h | 2 ++
31 contrib/intarray/_int_bool.c | 9 +++++++++
32 contrib/ltree/ltree.h | 3 +++
33 contrib/ltree/ltree_io.c | 11 +++++++++++
34 contrib/ltree/ltxtquery_io.c | 13 ++++++++++++-
35 src/backend/utils/adt/geo_ops.c | 30 ++++++++++++++++++++++++++++--
36 src/backend/utils/adt/tsquery.c | 7 ++++++-
37 src/backend/utils/adt/tsquery_util.c | 5 +++++
38 src/backend/utils/adt/txid.c | 15 +++++----------
39 src/backend/utils/adt/varbit.c | 32 ++++++++++++++++++++++++++++++--
40 src/include/tsearch/ts_type.h | 3 +++
41 src/include/utils/varbit.h | 7 +++++++
42 15 files changed, 169 insertions(+), 19 deletions(-)
43
44diff --git a/contrib/hstore/hstore.h b/contrib/hstore/hstore.h
45index 8906397..4e55f6e 100644
46--- a/contrib/hstore/hstore.h
47+++ b/contrib/hstore/hstore.h
48@@ -49,9 +49,12 @@ typedef struct
49 } HStore;
50
51 /*
52- * it's not possible to get more than 2^28 items into an hstore,
53- * so we reserve the top few bits of the size field. See hstore_compat.c
54- * for one reason why. Some bits are left for future use here.
55+ * It's not possible to get more than 2^28 items into an hstore, so we reserve
56+ * the top few bits of the size field. See hstore_compat.c for one reason
57+ * why. Some bits are left for future use here. MaxAllocSize makes the
58+ * practical count limit slightly more than 2^28 / 3, or INT_MAX / 24, the
59+ * limit for an hstore full of 4-byte keys and null values. Therefore, we
60+ * don't explicitly check the format-imposed limit.
61 */
62 #define HS_FLAG_NEWVERSION 0x80000000
63
64@@ -59,6 +62,12 @@ typedef struct
65 #define HS_SETCOUNT(hsp_,c_) ((hsp_)->size_ = (c_) | HS_FLAG_NEWVERSION)
66
67
68+/*
69+ * "x" comes from an existing HS_COUNT() (as discussed, <= INT_MAX/24) or a
70+ * Pairs array length (due to MaxAllocSize, <= INT_MAX/40). "lenstr" is no
71+ * more than INT_MAX, that extreme case arising in hstore_from_arrays().
72+ * Therefore, this calculation is limited to about INT_MAX / 5 + INT_MAX.
73+ */
74 #define HSHRDSIZE (sizeof(HStore))
75 #define CALCDATASIZE(x, lenstr) ( (x) * 2 * sizeof(HEntry) + HSHRDSIZE + (lenstr) )
76
77diff --git a/contrib/hstore/hstore_io.c b/contrib/hstore/hstore_io.c
78index dde6c4b..5bcdc95 100644
79--- a/contrib/hstore/hstore_io.c
80+++ b/contrib/hstore/hstore_io.c
81@@ -9,6 +9,7 @@
82 #include "funcapi.h"
83 #include "libpq/pqformat.h"
84 #include "utils/lsyscache.h"
85+#include "utils/memutils.h"
86 #include "utils/typcache.h"
87
88 #include "hstore.h"
89@@ -437,6 +438,11 @@ hstore_recv(PG_FUNCTION_ARGS)
90 PG_RETURN_POINTER(out);
91 }
92
93+ if (pcount < 0 || pcount > MaxAllocSize / sizeof(Pairs))
94+ ereport(ERROR,
95+ (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
96+ errmsg("number of pairs (%d) exceeds the maximum allowed (%d)",
97+ pcount, (int) (MaxAllocSize / sizeof(Pairs)))));
98 pairs = palloc(pcount * sizeof(Pairs));
99
100 for (i = 0; i < pcount; ++i)
101@@ -552,6 +558,13 @@ hstore_from_arrays(PG_FUNCTION_ARGS)
102 TEXTOID, -1, false, 'i',
103 &key_datums, &key_nulls, &key_count);
104
105+ /* see discussion in hstoreArrayToPairs() */
106+ if (key_count > MaxAllocSize / sizeof(Pairs))
107+ ereport(ERROR,
108+ (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
109+ errmsg("number of pairs (%d) exceeds the maximum allowed (%d)",
110+ key_count, (int) (MaxAllocSize / sizeof(Pairs)))));
111+
112 /* value_array might be NULL */
113
114 if (PG_ARGISNULL(1))
115@@ -674,6 +687,13 @@ hstore_from_array(PG_FUNCTION_ARGS)
116
117 count = in_count / 2;
118
119+ /* see discussion in hstoreArrayToPairs() */
120+ if (count > MaxAllocSize / sizeof(Pairs))
121+ ereport(ERROR,
122+ (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
123+ errmsg("number of pairs (%d) exceeds the maximum allowed (%d)",
124+ count, (int) (MaxAllocSize / sizeof(Pairs)))));
125+
126 pairs = palloc(count * sizeof(Pairs));
127
128 for (i = 0; i < count; ++i)
129@@ -805,6 +825,7 @@ hstore_from_record(PG_FUNCTION_ARGS)
130 my_extra->ncolumns = ncolumns;
131 }
132
133+ Assert(ncolumns <= MaxTupleAttributeNumber); /* thus, no overflow */
134 pairs = palloc(ncolumns * sizeof(Pairs));
135
136 if (rec)
137diff --git a/contrib/hstore/hstore_op.c b/contrib/hstore/hstore_op.c
138index fee2c3c..8de175a 100644
139--- a/contrib/hstore/hstore_op.c
140+++ b/contrib/hstore/hstore_op.c
141@@ -7,6 +7,7 @@
142 #include "catalog/pg_type.h"
143 #include "funcapi.h"
144 #include "utils/builtins.h"
145+#include "utils/memutils.h"
146
147 #include "hstore.h"
148
149@@ -89,6 +90,19 @@ hstoreArrayToPairs(ArrayType *a, int *npairs)
150 return NULL;
151 }
152
153+ /*
154+ * A text array uses at least eight bytes per element, so any overflow in
155+ * "key_count * sizeof(Pairs)" is small enough for palloc() to catch.
156+ * However, credible improvements to the array format could invalidate
157+ * that assumption. Therefore, use an explicit check rather than relying
158+ * on palloc() to complain.
159+ */
160+ if (key_count > MaxAllocSize / sizeof(Pairs))
161+ ereport(ERROR,
162+ (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
163+ errmsg("number of pairs (%d) exceeds the maximum allowed (%d)",
164+ key_count, (int) (MaxAllocSize / sizeof(Pairs)))));
165+
166 key_pairs = palloc(sizeof(Pairs) * key_count);
167
168 for (i = 0, j = 0; i < key_count; i++)
169@@ -647,6 +661,7 @@ hstore_slice_to_hstore(PG_FUNCTION_ARGS)
170 PG_RETURN_POINTER(out);
171 }
172
173+ /* hstoreArrayToPairs() checked overflow */
174 out_pairs = palloc(sizeof(Pairs) * nkeys);
175 bufsiz = 0;
176
177diff --git a/contrib/intarray/_int.h b/contrib/intarray/_int.h
178index 11c0698..755cd9e 100644
179--- a/contrib/intarray/_int.h
180+++ b/contrib/intarray/_int.h
181@@ -5,6 +5,7 @@
182 #define ___INT_H__
183
184 #include "utils/array.h"
185+#include "utils/memutils.h"
186
187 /* number ranges for compression */
188 #define MAXNUMRANGE 100
189@@ -137,6 +138,7 @@ typedef struct QUERYTYPE
190
191 #define HDRSIZEQT offsetof(QUERYTYPE, items)
192 #define COMPUTESIZE(size) ( HDRSIZEQT + (size) * sizeof(ITEM) )
193+#define QUERYTYPEMAXITEMS ((MaxAllocSize - HDRSIZEQT) / sizeof(ITEM))
194 #define GETQUERY(x) ( (x)->items )
195
196 /* "type" codes for ITEM */
197diff --git a/contrib/intarray/_int_bool.c b/contrib/intarray/_int_bool.c
198index 4e63f6d..62294d1 100644
199--- a/contrib/intarray/_int_bool.c
200+++ b/contrib/intarray/_int_bool.c
201@@ -451,6 +451,9 @@ boolop(PG_FUNCTION_ARGS)
202 static void
203 findoprnd(ITEM *ptr, int4 *pos)
204 {
205+ /* since this function recurses, it could be driven to stack overflow. */
206+ check_stack_depth();
207+
208 #ifdef BS_DEBUG
209 elog(DEBUG3, (ptr[*pos].type == OPR) ?
210 "%d %c" : "%d %d", *pos, ptr[*pos].val);
211@@ -511,7 +514,13 @@ bqarr_in(PG_FUNCTION_ARGS)
212 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
213 errmsg("empty query")));
214
215+ if (state.num > QUERYTYPEMAXITEMS)
216+ ereport(ERROR,
217+ (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
218+ errmsg("number of query items (%d) exceeds the maximum allowed (%d)",
219+ state.num, (int) QUERYTYPEMAXITEMS)));
220 commonlen = COMPUTESIZE(state.num);
221+
222 query = (QUERYTYPE *) palloc(commonlen);
223 SET_VARSIZE(query, commonlen);
224 query->size = state.num;
225diff --git a/contrib/ltree/ltree.h b/contrib/ltree/ltree.h
226index aec4458..49e9907 100644
227--- a/contrib/ltree/ltree.h
228+++ b/contrib/ltree/ltree.h
229@@ -5,6 +5,7 @@
230
231 #include "fmgr.h"
232 #include "tsearch/ts_locale.h"
233+#include "utils/memutils.h"
234
235 typedef struct
236 {
237@@ -111,6 +112,8 @@ typedef struct
238
239 #define HDRSIZEQT MAXALIGN(VARHDRSZ + sizeof(int4))
240 #define COMPUTESIZE(size,lenofoperand) ( HDRSIZEQT + (size) * sizeof(ITEM) + (lenofoperand) )
241+#define LTXTQUERY_TOO_BIG(size,lenofoperand) \
242+ ((size) > (MaxAllocSize - HDRSIZEQT - (lenofoperand)) / sizeof(ITEM))
243 #define GETQUERY(x) (ITEM*)( (char*)(x)+HDRSIZEQT )
244 #define GETOPERAND(x) ( (char*)GETQUERY(x) + ((ltxtquery*)x)->size * sizeof(ITEM) )
245
246diff --git a/contrib/ltree/ltree_io.c b/contrib/ltree/ltree_io.c
247index 3e88b81..d64debb 100644
248--- a/contrib/ltree/ltree_io.c
249+++ b/contrib/ltree/ltree_io.c
250@@ -8,6 +8,7 @@
251 #include <ctype.h>
252
253 #include "ltree.h"
254+#include "utils/memutils.h"
255 #include "crc32.h"
256
257 PG_FUNCTION_INFO_V1(ltree_in);
258@@ -64,6 +65,11 @@ ltree_in(PG_FUNCTION_ARGS)
259 ptr += charlen;
260 }
261
262+ if (num + 1 > MaxAllocSize / sizeof(nodeitem))
263+ ereport(ERROR,
264+ (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
265+ errmsg("number of levels (%d) exceeds the maximum allowed (%d)",
266+ num + 1, (int) (MaxAllocSize / sizeof(nodeitem)))));
267 list = lptr = (nodeitem *) palloc(sizeof(nodeitem) * (num + 1));
268 ptr = buf;
269 while (*ptr)
270@@ -228,6 +234,11 @@ lquery_in(PG_FUNCTION_ARGS)
271 }
272
273 num++;
274+ if (num > MaxAllocSize / ITEMSIZE)
275+ ereport(ERROR,
276+ (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
277+ errmsg("number of levels (%d) exceeds the maximum allowed (%d)",
278+ num, (int) (MaxAllocSize / ITEMSIZE))));
279 curqlevel = tmpql = (lquery_level *) palloc0(ITEMSIZE * num);
280 ptr = buf;
281 while (*ptr)
282diff --git a/contrib/ltree/ltxtquery_io.c b/contrib/ltree/ltxtquery_io.c
283index 826f4e1..13ea58d 100644
284--- a/contrib/ltree/ltxtquery_io.c
285+++ b/contrib/ltree/ltxtquery_io.c
286@@ -9,6 +9,7 @@
287
288 #include "crc32.h"
289 #include "ltree.h"
290+#include "miscadmin.h"
291
292 PG_FUNCTION_INFO_V1(ltxtq_in);
293 Datum ltxtq_in(PG_FUNCTION_ARGS);
294@@ -213,6 +214,9 @@ makepol(QPRS_STATE *state)
295 int4 lenstack = 0;
296 uint16 flag = 0;
297
298+ /* since this function recurses, it could be driven to stack overflow */
299+ check_stack_depth();
300+
301 while ((type = gettoken_query(state, &val, &lenval, &strval, &flag)) != END)
302 {
303 switch (type)
304@@ -277,6 +281,9 @@ makepol(QPRS_STATE *state)
305 static void
306 findoprnd(ITEM *ptr, int4 *pos)
307 {
308+ /* since this function recurses, it could be driven to stack overflow. */
309+ check_stack_depth();
310+
311 if (ptr[*pos].type == VAL || ptr[*pos].type == VALTRUE)
312 {
313 ptr[*pos].left = 0;
314@@ -341,8 +348,12 @@ queryin(char *buf)
315 errmsg("syntax error"),
316 errdetail("Empty query.")));
317
318- /* make finish struct */
319+ if (LTXTQUERY_TOO_BIG(state.num, state.sumlen))
320+ ereport(ERROR,
321+ (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
322+ errmsg("ltxtquery is too large")));
323 commonlen = COMPUTESIZE(state.num, state.sumlen);
324+
325 query = (ltxtquery *) palloc(commonlen);
326 SET_VARSIZE(query, commonlen);
327 query->size = state.num;
328diff --git a/src/backend/utils/adt/geo_ops.c b/src/backend/utils/adt/geo_ops.c
329index ac7b4b8..7ebcaaa 100644
330--- a/src/backend/utils/adt/geo_ops.c
331+++ b/src/backend/utils/adt/geo_ops.c
332@@ -1403,6 +1403,7 @@ path_in(PG_FUNCTION_ARGS)
333 char *s;
334 int npts;
335 int size;
336+ int base_size;
337 int depth = 0;
338
339 if ((npts = pair_count(str, ',')) <= 0)
340@@ -1421,7 +1422,15 @@ path_in(PG_FUNCTION_ARGS)
341 depth++;
342 }
343
344- size = offsetof(PATH, p[0]) +sizeof(path->p[0]) * npts;
345+ base_size = sizeof(path->p[0]) * npts;
346+ size = offsetof(PATH, p[0]) + base_size;
347+
348+ /* Check for integer overflow */
349+ if (base_size / npts != sizeof(path->p[0]) || size <= base_size)
350+ ereport(ERROR,
351+ (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
352+ errmsg("too many points requested")));
353+
354 path = (PATH *) palloc(size);
355
356 SET_VARSIZE(path, size);
357@@ -3465,6 +3474,7 @@ poly_in(PG_FUNCTION_ARGS)
358 POLYGON *poly;
359 int npts;
360 int size;
361+ int base_size;
362 int isopen;
363 char *s;
364
365@@ -3473,7 +3483,15 @@ poly_in(PG_FUNCTION_ARGS)
366 (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
367 errmsg("invalid input syntax for type polygon: \"%s\"", str)));
368
369- size = offsetof(POLYGON, p[0]) +sizeof(poly->p[0]) * npts;
370+ base_size = sizeof(poly->p[0]) * npts;
371+ size = offsetof(POLYGON, p[0]) + base_size;
372+
373+ /* Check for integer overflow */
374+ if (base_size / npts != sizeof(poly->p[0]) || size <= base_size)
375+ ereport(ERROR,
376+ (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
377+ errmsg("too many points requested")));
378+
379 poly = (POLYGON *) palloc0(size); /* zero any holes */
380
381 SET_VARSIZE(poly, size);
382@@ -4379,6 +4397,10 @@ path_poly(PG_FUNCTION_ARGS)
383 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
384 errmsg("open path cannot be converted to polygon")));
385
386+ /*
387+ * Never overflows: the old size fit in MaxAllocSize, and the new size is
388+ * just a small constant larger.
389+ */
390 size = offsetof(POLYGON, p[0]) +sizeof(poly->p[0]) * path->npts;
391 poly = (POLYGON *) palloc(size);
392
393@@ -4484,6 +4506,10 @@ poly_path(PG_FUNCTION_ARGS)
394 int size;
395 int i;
396
397+ /*
398+ * Never overflows: the old size fit in MaxAllocSize, and the new size is
399+ * smaller by a small constant.
400+ */
401 size = offsetof(PATH, p[0]) +sizeof(path->p[0]) * poly->npts;
402 path = (PATH *) palloc(size);
403
404diff --git a/src/backend/utils/adt/tsquery.c b/src/backend/utils/adt/tsquery.c
405index 6e1f8cf..1322b5e 100644
406--- a/src/backend/utils/adt/tsquery.c
407+++ b/src/backend/utils/adt/tsquery.c
408@@ -515,8 +515,13 @@ parse_tsquery(char *buf,
409 return query;
410 }
411
412- /* Pack the QueryItems in the final TSQuery struct to return to caller */
413+ if (TSQUERY_TOO_BIG(list_length(state.polstr), state.sumlen))
414+ ereport(ERROR,
415+ (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
416+ errmsg("tsquery is too large")));
417 commonlen = COMPUTESIZE(list_length(state.polstr), state.sumlen);
418+
419+ /* Pack the QueryItems in the final TSQuery struct to return to caller */
420 query = (TSQuery) palloc0(commonlen);
421 SET_VARSIZE(query, commonlen);
422 query->size = list_length(state.polstr);
423diff --git a/src/backend/utils/adt/tsquery_util.c b/src/backend/utils/adt/tsquery_util.c
424index 0724d33..9003702 100644
425--- a/src/backend/utils/adt/tsquery_util.c
426+++ b/src/backend/utils/adt/tsquery_util.c
427@@ -333,6 +333,11 @@ QTN2QT(QTNode *in)
428 QTN2QTState state;
429
430 cntsize(in, &sumlen, &nnode);
431+
432+ if (TSQUERY_TOO_BIG(nnode, sumlen))
433+ ereport(ERROR,
434+ (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
435+ errmsg("tsquery is too large")));
436 len = COMPUTESIZE(nnode, sumlen);
437
438 out = (TSQuery) palloc0(len);
439diff --git a/src/backend/utils/adt/txid.c b/src/backend/utils/adt/txid.c
440index 08a8c89..c71daaf 100644
441--- a/src/backend/utils/adt/txid.c
442+++ b/src/backend/utils/adt/txid.c
443@@ -27,6 +27,7 @@
444 #include "miscadmin.h"
445 #include "libpq/pqformat.h"
446 #include "utils/builtins.h"
447+#include "utils/memutils.h"
448 #include "utils/snapmgr.h"
449
450
451@@ -66,6 +67,8 @@ typedef struct
452
453 #define TXID_SNAPSHOT_SIZE(nxip) \
454 (offsetof(TxidSnapshot, xip) + sizeof(txid) * (nxip))
455+#define TXID_SNAPSHOT_MAX_NXIP \
456+ ((MaxAllocSize - offsetof(TxidSnapshot, xip)) / sizeof(txid))
457
458 /*
459 * Epoch values from xact.c
460@@ -445,20 +448,12 @@ txid_snapshot_recv(PG_FUNCTION_ARGS)
461 txid last = 0;
462 int nxip;
463 int i;
464- int avail;
465- int expect;
466 txid xmin,
467 xmax;
468
469- /*
470- * load nxip and check for nonsense.
471- *
472- * (nxip > avail) check is against int overflows in 'expect'.
473- */
474+ /* load and validate nxip */
475 nxip = pq_getmsgint(buf, 4);
476- avail = buf->len - buf->cursor;
477- expect = 8 + 8 + nxip * 8;
478- if (nxip < 0 || nxip > avail || expect > avail)
479+ if (nxip < 0 || nxip > TXID_SNAPSHOT_MAX_NXIP)
480 goto bad_format;
481
482 xmin = pq_getmsgint64(buf);
483diff --git a/src/backend/utils/adt/varbit.c b/src/backend/utils/adt/varbit.c
484index 2bcf5b8..0deefda 100644
485--- a/src/backend/utils/adt/varbit.c
486+++ b/src/backend/utils/adt/varbit.c
487@@ -148,12 +148,22 @@ bit_in(PG_FUNCTION_ARGS)
488 sp = input_string;
489 }
490
491+ /*
492+ * Determine bitlength from input string. MaxAllocSize ensures a regular
493+ * input is small enough, but we must check hex input.
494+ */
495 slen = strlen(sp);
496- /* Determine bitlength from input string */
497 if (bit_not_hex)
498 bitlen = slen;
499 else
500+ {
501+ if (slen > VARBITMAXLEN / 4)
502+ ereport(ERROR,
503+ (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
504+ errmsg("bit string length exceeds the maximum allowed (%d)",
505+ VARBITMAXLEN)));
506 bitlen = slen * 4;
507+ }
508
509 /*
510 * Sometimes atttypmod is not supplied. If it is supplied we need to make
511@@ -450,12 +460,22 @@ varbit_in(PG_FUNCTION_ARGS)
512 sp = input_string;
513 }
514
515+ /*
516+ * Determine bitlength from input string. MaxAllocSize ensures a regular
517+ * input is small enough, but we must check hex input.
518+ */
519 slen = strlen(sp);
520- /* Determine bitlength from input string */
521 if (bit_not_hex)
522 bitlen = slen;
523 else
524+ {
525+ if (slen > VARBITMAXLEN / 4)
526+ ereport(ERROR,
527+ (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
528+ errmsg("bit string length exceeds the maximum allowed (%d)",
529+ VARBITMAXLEN)));
530 bitlen = slen * 4;
531+ }
532
533 /*
534 * Sometimes atttypmod is not supplied. If it is supplied we need to make
535@@ -535,6 +555,9 @@ varbit_in(PG_FUNCTION_ARGS)
536 /*
537 * varbit_out -
538 * Prints the string as bits to preserve length accurately
539+ *
540+ * XXX varbit_recv() and hex input to varbit_in() can load a value that this
541+ * cannot emit. Consider using hex output for such values.
542 */
543 Datum
544 varbit_out(PG_FUNCTION_ARGS)
545@@ -944,6 +967,11 @@ bit_catenate(VarBit *arg1, VarBit *arg2)
546 bitlen1 = VARBITLEN(arg1);
547 bitlen2 = VARBITLEN(arg2);
548
549+ if (bitlen1 > VARBITMAXLEN - bitlen2)
550+ ereport(ERROR,
551+ (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
552+ errmsg("bit string length exceeds the maximum allowed (%d)",
553+ VARBITMAXLEN)));
554 bytelen = VARBITTOTALLEN(bitlen1 + bitlen2);
555
556 result = (VarBit *) palloc(bytelen);
557diff --git a/src/include/tsearch/ts_type.h b/src/include/tsearch/ts_type.h
558index 3adc336..9ee5610 100644
559--- a/src/include/tsearch/ts_type.h
560+++ b/src/include/tsearch/ts_type.h
561@@ -13,6 +13,7 @@
562 #define _PG_TSTYPE_H_
563
564 #include "fmgr.h"
565+#include "utils/memutils.h"
566 #include "utils/pg_crc.h"
567
568
569@@ -244,6 +245,8 @@ typedef TSQueryData *TSQuery;
570 * QueryItems, and lenofoperand is the total length of all operands
571 */
572 #define COMPUTESIZE(size, lenofoperand) ( HDRSIZETQ + (size) * sizeof(QueryItem) + (lenofoperand) )
573+#define TSQUERY_TOO_BIG(size, lenofoperand) \
574+ ((size) > (MaxAllocSize - HDRSIZETQ - (lenofoperand)) / sizeof(QueryItem))
575
576 /* Returns a pointer to the first QueryItem in a TSQuery */
577 #define GETQUERY(x) ((QueryItem*)( (char*)(x)+HDRSIZETQ ))
578diff --git a/src/include/utils/varbit.h b/src/include/utils/varbit.h
579index 52dca8b..61531a8 100644
580--- a/src/include/utils/varbit.h
581+++ b/src/include/utils/varbit.h
582@@ -15,6 +15,8 @@
583 #ifndef VARBIT_H
584 #define VARBIT_H
585
586+#include <limits.h>
587+
588 #include "fmgr.h"
589
590 /*
591@@ -53,6 +55,11 @@ typedef struct
592 /* Number of bytes needed to store a bit string of a given length */
593 #define VARBITTOTALLEN(BITLEN) (((BITLEN) + BITS_PER_BYTE-1)/BITS_PER_BYTE + \
594 VARHDRSZ + VARBITHDRSZ)
595+/*
596+ * Maximum number of bits. Several code sites assume no overflow from
597+ * computing bitlen + X; VARBITTOTALLEN() has the largest such X.
598+ */
599+#define VARBITMAXLEN (INT_MAX - BITS_PER_BYTE + 1)
600 /* pointer beyond the end of the bit string (like end() in STL containers) */
601 #define VARBITEND(PTR) (((bits8 *) (PTR)) + VARSIZE(PTR))
602 /* Mask that will cover exactly one byte, i.e. BITS_PER_BYTE bits */
603--
6041.7.5.4
605
diff --git a/meta-oe/recipes-support/postgresql/postgresql.inc b/meta-oe/recipes-support/postgresql/postgresql.inc
index d45f4b5ed..9b242e047 100644
--- a/meta-oe/recipes-support/postgresql/postgresql.inc
+++ b/meta-oe/recipes-support/postgresql/postgresql.inc
@@ -28,10 +28,11 @@ SRC_URI = "http://ftp.postgresql.org/pub/source/v${PV}/${BP}.tar.bz2 \
28 file://postgresql.init \ 28 file://postgresql.init \
29 file://postgresql-bashprofile \ 29 file://postgresql-bashprofile \
30 file://postgresql.pam \ 30 file://postgresql.pam \
31 file://0001-Use-pkg-config-for-libxml2-detection.patch \
32 file://postgresql-setup \ 31 file://postgresql-setup \
33 file://postgresql.service \ 32 file://postgresql.service \
34" 33 file://0001-Use-pkg-config-for-libxml2-detection.patch \
34 file://0002-Predict-integer-overflow-to-avoid-buffer-overruns.patch \
35 "
35 36
36LEAD_SONAME = "libpq.so" 37LEAD_SONAME = "libpq.so"
37 38