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
This commit is contained in:
Bruce Momjian 2002-08-29 23:05:44 +00:00
parent dbc4d615ca
commit 9858a3a43f
1 changed files with 30 additions and 9 deletions

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/utils/adt/geo_ops.c,v 1.63 2002/07/16 03:30:27 momjian Exp $ * $Header: /cvsroot/pgsql/src/backend/utils/adt/geo_ops.c,v 1.64 2002/08/29 23:05:44 momjian Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -269,11 +269,17 @@ path_decode(int opentype, int npts, char *str, int *isopen, char **ss, Point *p)
static char * static char *
path_encode(bool closed, int npts, Point *pt) path_encode(bool closed, int npts, Point *pt)
{ {
char *result = palloc(npts * (P_MAXLEN + 3) + 2); int size = npts * (P_MAXLEN + 3) + 2;
char *result;
char *cp; char *cp;
int i; int i;
/* Check for integer overflow */
if ((size - 2) / npts != (P_MAXLEN + 3))
elog(ERROR, "Too many points requested");
result = palloc(size);
cp = result; cp = result;
switch (closed) switch (closed)
{ {
@ -1230,7 +1236,7 @@ path_in(PG_FUNCTION_ARGS)
depth++; depth++;
} }
size = offsetof(PATH, p[0]) +sizeof(path->p[0]) * npts; size = offsetof(PATH, p[0]) + sizeof(path->p[0]) * npts;
path = (PATH *) palloc(size); path = (PATH *) palloc(size);
path->size = size; path->size = size;
@ -3596,13 +3602,21 @@ path_add(PG_FUNCTION_ARGS)
PATH *p1 = PG_GETARG_PATH_P(0); PATH *p1 = PG_GETARG_PATH_P(0);
PATH *p2 = PG_GETARG_PATH_P(1); PATH *p2 = PG_GETARG_PATH_P(1);
PATH *result; PATH *result;
int size; int size,
base_size;
int i; int i;
if (p1->closed || p2->closed) if (p1->closed || p2->closed)
PG_RETURN_NULL(); PG_RETURN_NULL();
size = offsetof(PATH, p[0]) +sizeof(p1->p[0]) * (p1->npts + p2->npts); base_size = sizeof(p1->p[0]) * (p1->npts + p2->npts);
size = offsetof(PATH, p[0]) + base_size;
/* Check for integer overflow */
if (base_size / sizeof(p1->p[0]) != (p1->npts + p2->npts) ||
size <= base_size)
elog(ERROR, "too many points requested.");
result = (PATH *) palloc(size); result = (PATH *) palloc(size);
result->size = size; result->size = size;
@ -4413,17 +4427,24 @@ circle_poly(PG_FUNCTION_ARGS)
int32 npts = PG_GETARG_INT32(0); int32 npts = PG_GETARG_INT32(0);
CIRCLE *circle = PG_GETARG_CIRCLE_P(1); CIRCLE *circle = PG_GETARG_CIRCLE_P(1);
POLYGON *poly; POLYGON *poly;
int size; int base_size,
size;
int i; int i;
double angle; double angle;
if (FPzero(circle->radius) || (npts < 2)) if (FPzero(circle->radius) || (npts < 2))
elog(ERROR, "Unable to convert circle to polygon"); elog(ERROR, "Unable to convert circle to polygon");
size = offsetof(POLYGON, p[0]) +(sizeof(poly->p[0]) * npts); base_size = sizeof(poly->p[0]) * npts;
size = offsetof(POLYGON, p[0]) + base_size;
/* Check for integer overflow */
if (base_size / npts != sizeof(poly->p[0]) || size <= base_size)
elog(ERROR, "too many points requested");
poly = (POLYGON *) palloc(size); poly = (POLYGON *) palloc(size);
MemSet((char *) poly, 0, size); /* zero any holes */ MemSet(poly, 0, size); /* zero any holes */
poly->size = size; poly->size = size;
poly->npts = npts; poly->npts = npts;