Semmle: Fix possible infite loops caused by overflow (#3503)

Comparison between differently sized integers in loop conditions can cause
infinite loops. This can happen when doing something like this:

```c
int64 very_big = MAX_INT32 + 1;
for (int32 i = 0; i < very_big; i++) {
    // do something
}
// never reached because i overflows before it can reach the value of very_big
```
pull/3361/head
Jelte Fennema 2020-02-17 14:35:10 +01:00 committed by GitHub
parent 15f1173b1d
commit 3f7c5a5cf6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 19 additions and 12 deletions

View File

@ -76,7 +76,7 @@ InitConnParams()
void void
ResetConnParams() ResetConnParams()
{ {
for (Index paramIdx = 0; paramIdx < ConnParams.size; paramIdx++) for (Size paramIdx = 0; paramIdx < ConnParams.size; paramIdx++)
{ {
free((void *) ConnParams.keywords[paramIdx]); free((void *) ConnParams.keywords[paramIdx]);
free((void *) ConnParams.values[paramIdx]); free((void *) ConnParams.values[paramIdx]);
@ -135,7 +135,6 @@ CheckConninfo(const char *conninfo, const char **whitelist,
Size whitelistLength, char **errorMsg) Size whitelistLength, char **errorMsg)
{ {
PQconninfoOption *option = NULL; PQconninfoOption *option = NULL;
Index whitelistIdx PG_USED_FOR_ASSERTS_ONLY = 0;
char *errorMsgString = NULL; char *errorMsgString = NULL;
/* /*
@ -174,7 +173,7 @@ CheckConninfo(const char *conninfo, const char **whitelist,
#ifdef USE_ASSERT_CHECKING #ifdef USE_ASSERT_CHECKING
/* verify that the whitelist is in ascending order */ /* verify that the whitelist is in ascending order */
for (whitelistIdx = 1; whitelistIdx < whitelistLength; whitelistIdx++) for (Size whitelistIdx = 1; whitelistIdx < whitelistLength; whitelistIdx++)
{ {
const char *prev = whitelist[whitelistIdx - 1]; const char *prev = whitelist[whitelistIdx - 1];
const char *curr = whitelist[whitelistIdx]; const char *curr = whitelist[whitelistIdx];
@ -290,7 +289,7 @@ GetConnParams(ConnectionHashKey *key, char ***keywords, char ***values,
pg_ltoa(key->port, nodePortString); /* populate node port string with port */ pg_ltoa(key->port, nodePortString); /* populate node port string with port */
/* first step: copy global parameters to beginning of array */ /* first step: copy global parameters to beginning of array */
for (Index paramIndex = 0; paramIndex < ConnParams.size; paramIndex++) for (Size paramIndex = 0; paramIndex < ConnParams.size; paramIndex++)
{ {
/* copy the keyword&value pointers to the new array */ /* copy the keyword&value pointers to the new array */
connKeywords[paramIndex] = ConnParams.keywords[paramIndex]; connKeywords[paramIndex] = ConnParams.keywords[paramIndex];
@ -328,7 +327,7 @@ GetConnParams(ConnectionHashKey *key, char ***keywords, char ***values,
const char * const char *
GetConnParam(const char *keyword) GetConnParam(const char *keyword)
{ {
for (Index i = 0; i < ConnParams.size; i++) for (Size i = 0; i < ConnParams.size; i++)
{ {
if (strcmp(keyword, ConnParams.keywords[i]) == 0) if (strcmp(keyword, ConnParams.keywords[i]) == 0)
{ {

View File

@ -524,7 +524,13 @@ pg_get_tablecolumnoptionsdef_string(Oid tableRelationId)
*/ */
TupleDesc tupleDescriptor = RelationGetDescr(relation); TupleDesc tupleDescriptor = RelationGetDescr(relation);
for (AttrNumber attributeIndex = 0; attributeIndex < tupleDescriptor->natts; if (tupleDescriptor->natts > MaxAttrNumber)
{
ereport(ERROR, (errmsg("bad number of tuple descriptor attributes")));
}
for (AttrNumber attributeIndex = 0;
attributeIndex < (AttrNumber) tupleDescriptor->natts;
attributeIndex++) attributeIndex++)
{ {
Form_pg_attribute attributeForm = TupleDescAttr(tupleDescriptor, attributeIndex); Form_pg_attribute attributeForm = TupleDescAttr(tupleDescriptor, attributeIndex);

View File

@ -1397,7 +1397,11 @@ TransformFunctionRTE(RangeTblEntry *rangeTblEntry)
* *
* We will iterate over Tuple Description attributes. i.e (c1 int, c2 text) * We will iterate over Tuple Description attributes. i.e (c1 int, c2 text)
*/ */
for (targetColumnIndex = 0; targetColumnIndex < tupleDesc->natts; if (tupleDesc->natts > MaxAttrNumber)
{
ereport(ERROR, (errmsg("bad number of tuple descriptor attributes")));
}
for (targetColumnIndex = 0; targetColumnIndex < (AttrNumber) tupleDesc->natts;
targetColumnIndex++) targetColumnIndex++)
{ {
FormData_pg_attribute *attribute = TupleDescAttr(tupleDesc, FormData_pg_attribute *attribute = TupleDescAttr(tupleDesc,

View File

@ -611,7 +611,7 @@ LocalNodeCitusDistStat(const char *statQuery, const char *hostname, int port)
*/ */
oldContext = MemoryContextSwitchTo(upperContext); oldContext = MemoryContextSwitchTo(upperContext);
for (uint32 rowIndex = 0; rowIndex < SPI_processed; rowIndex++) for (uint64 rowIndex = 0; rowIndex < SPI_processed; rowIndex++)
{ {
TupleDesc rowDescriptor = SPI_tuptable->tupdesc; TupleDesc rowDescriptor = SPI_tuptable->tupdesc;

View File

@ -242,8 +242,6 @@ LockAcquireHelperMain(Datum main_arg)
while (ShouldAcquireLock(100)) while (ShouldAcquireLock(100))
{ {
int row = 0;
elog(LOG, "canceling competing backends for backend %d", backendPid); elog(LOG, "canceling competing backends for backend %d", backendPid);
/* /*
@ -261,7 +259,7 @@ LockAcquireHelperMain(Datum main_arg)
if (spiStatus == SPI_OK_SELECT) if (spiStatus == SPI_OK_SELECT)
{ {
for (row = 0; row < SPI_processed; row++) for (uint64 row = 0; row < SPI_processed; row++)
{ {
bool isnull = false; bool isnull = false;

View File

@ -936,7 +936,7 @@ FilterAndPartitionTable(const char *filterQuery,
while (SPI_processed > 0) while (SPI_processed > 0)
{ {
for (int rowIndex = 0; rowIndex < SPI_processed; rowIndex++) for (uint64 rowIndex = 0; rowIndex < SPI_processed; rowIndex++)
{ {
HeapTuple row = SPI_tuptable->vals[rowIndex]; HeapTuple row = SPI_tuptable->vals[rowIndex];
TupleDesc rowDescriptor = SPI_tuptable->tupdesc; TupleDesc rowDescriptor = SPI_tuptable->tupdesc;