Skip to content

Commit 9858a3a

Browse files
committed
Sir Mordred The Traitor <mordred@s-mail.com> writes:
> Upon invoking a polygon(integer, circle) function a > src/backend/utils/adt/geo_ops.c:circle_poly() function will gets > called, which suffers from a buffer overflow. > > 2) A src/backend/adt/utils/geo_ops.c:path_encode() fails to detect a > buffer overrun condition. It is called in multiple places, the most > interesting are path_out() and poly_out() functions. > 5) A src/backend/utils/adt/geo_ops.c:path_add() also fails to detect > a simple buffer overrun. I've attached a patch which should fix these problems. Neil Conway
1 parent dbc4d61 commit 9858a3a

File tree

1 file changed

+30
-9
lines changed

1 file changed

+30
-9
lines changed

src/backend/utils/adt/geo_ops.c

Lines changed: 30 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/backend/utils/adt/geo_ops.c,v 1.63 2002/07/16 03:30:27 momjian Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/utils/adt/geo_ops.c,v 1.64 2002/08/29 23:05:44 momjian Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -269,11 +269,17 @@ path_decode(int opentype, int npts, char *str, int *isopen, char **ss, Point *p)
269269
static char *
270270
path_encode(bool closed, int npts, Point *pt)
271271
{
272-
char *result = palloc(npts * (P_MAXLEN + 3) + 2);
273-
272+
int size = npts * (P_MAXLEN + 3) + 2;
273+
char *result;
274274
char *cp;
275275
int i;
276276

277+
/* Check for integer overflow */
278+
if ((size - 2) / npts != (P_MAXLEN + 3))
279+
elog(ERROR, "Too many points requested");
280+
281+
result = palloc(size);
282+
277283
cp = result;
278284
switch (closed)
279285
{
@@ -1230,7 +1236,7 @@ path_in(PG_FUNCTION_ARGS)
12301236
depth++;
12311237
}
12321238

1233-
size = offsetof(PATH, p[0]) +sizeof(path->p[0]) * npts;
1239+
size = offsetof(PATH, p[0]) + sizeof(path->p[0]) * npts;
12341240
path = (PATH *) palloc(size);
12351241

12361242
path->size = size;
@@ -3596,13 +3602,21 @@ path_add(PG_FUNCTION_ARGS)
35963602
PATH *p1 = PG_GETARG_PATH_P(0);
35973603
PATH *p2 = PG_GETARG_PATH_P(1);
35983604
PATH *result;
3599-
int size;
3605+
int size,
3606+
base_size;
36003607
int i;
36013608

36023609
if (p1->closed || p2->closed)
36033610
PG_RETURN_NULL();
36043611

3605-
size = offsetof(PATH, p[0]) +sizeof(p1->p[0]) * (p1->npts + p2->npts);
3612+
base_size = sizeof(p1->p[0]) * (p1->npts + p2->npts);
3613+
size = offsetof(PATH, p[0]) + base_size;
3614+
3615+
/* Check for integer overflow */
3616+
if (base_size / sizeof(p1->p[0]) != (p1->npts + p2->npts) ||
3617+
size <= base_size)
3618+
elog(ERROR, "too many points requested.");
3619+
36063620
result = (PATH *) palloc(size);
36073621

36083622
result->size = size;
@@ -4413,17 +4427,24 @@ circle_poly(PG_FUNCTION_ARGS)
44134427
int32 npts = PG_GETARG_INT32(0);
44144428
CIRCLE *circle = PG_GETARG_CIRCLE_P(1);
44154429
POLYGON *poly;
4416-
int size;
4430+
int base_size,
4431+
size;
44174432
int i;
44184433
double angle;
44194434

44204435
if (FPzero(circle->radius) || (npts < 2))
44214436
elog(ERROR, "Unable to convert circle to polygon");
44224437

4423-
size = offsetof(POLYGON, p[0]) +(sizeof(poly->p[0]) * npts);
4438+
base_size = sizeof(poly->p[0]) * npts;
4439+
size = offsetof(POLYGON, p[0]) + base_size;
4440+
4441+
/* Check for integer overflow */
4442+
if (base_size / npts != sizeof(poly->p[0]) || size <= base_size)
4443+
elog(ERROR, "too many points requested");
4444+
44244445
poly = (POLYGON *) palloc(size);
44254446

4426-
MemSet((char *) poly, 0, size); /* zero any holes */
4447+
MemSet(poly, 0, size); /* zero any holes */
44274448
poly->size = size;
44284449
poly->npts = npts;
44294450

0 commit comments

Comments
 (0)