BUG #19429: An issue regarding the processing of Oid as an int type in ecpg - Mailing list pgsql-bugs

From PG Bug reporting form
Subject BUG #19429: An issue regarding the processing of Oid as an int type in ecpg
Date
Msg-id 19429-aead3b1874be1a99@postgresql.org
Whole thread Raw
Responses Re: BUG #19429: An issue regarding the processing of Oid as an int type in ecpg
List pgsql-bugs
The following bug has been logged on the website:

Bug reference:      19429
Logged by:          fairyfar
Email address:      fairyfar@msn.com
PostgreSQL version: 18.3
Operating system:   Linux
Description:

An issue regarding the processing of Oid as an int type in ecpg.

PostgreSQL version: 18.3 (the other ones are the same).

Part of the code caches and calculates the Oid as an int type in ecpg.
We know that Oid is unsigned int. When the Oid value is greater than or
equal to 2^31, it exceeds the value range of the int type. There are
potential problems in processing Oid with the int type. For example, when
formatting Oid with "%d", negative values may occur.

Through analysis and testing, it is found that the ecpg part of the code has
not caused any problems so far, but it is running in an obscure way.

For example, suppose the current value of Oid next is 2^31, the user creates
a custom data type and creates a table using this type:

```sql
-- An array type named _mytype will be automatically created.
-- Suppose the Oid of the _mytype type created by the following SQL is
2147483648 (i.e., 2^31).
create type mytype as (x int, y int);
create table t1 (a _mytype);
insert into t1 values (array[row(111, 222)::mytype]);
```

Use the following test.pgc code to read the data in table t1:

```
int main()
{
EXEC SQL BEGIN DECLARE SECTION;
    char str[256];
EXEC SQL END DECLARE SECTION;

    EXEC SQL CONNECT TO 'tcp:postgresql://localhost:5432/postgres' as ffdb
USER fairyfar;
    EXEC SQL SELECT a INTO :str FROM t1;
    printf("%s\n", str);
    EXEC SQL DISCONNECT ffdb;
    return 0;
}
```

After compiling, running and debugging the code. It can be known that the
content of array_query variable will be set as "select typlen from pg_type
where oid=-2147483648 and typelem<>0" on
src/interfaces/ecpg/ecpglib/execute.c:270.

Although this select query can be executed correctly, it is running in a
strange and coincidental way:
1. The Oid passes a negative value.
2. In grammar parsing, the pg_strtoint32_safe function enters the "out of
range" logic, but does not explicitly report an error.

It is recommended to make the following patches to eliminate potential
risks.

```
diff --git a/src/interfaces/ecpg/ecpglib/ecpglib_extern.h
b/src/interfaces/ecpg/ecpglib/ecpglib_extern.h
index 949ff66cefc..bea1398fce8 100644
--- a/src/interfaces/ecpg/ecpglib/ecpglib_extern.h
+++ b/src/interfaces/ecpg/ecpglib/ecpglib_extern.h
@@ -52,7 +52,7 @@ struct ECPGgeneric_bytea
 struct ECPGtype_information_cache
 {
        struct ECPGtype_information_cache *next;
-       int                     oid;
+       Oid                     oid;
        enum ARRAY_TYPE isarray;
 };

diff --git a/src/interfaces/ecpg/ecpglib/execute.c
b/src/interfaces/ecpg/ecpglib/execute.c
index bd10fef5748..b8dd0861ef6 100644
--- a/src/interfaces/ecpg/ecpglib/execute.c
+++ b/src/interfaces/ecpg/ecpglib/execute.c
@@ -145,7 +145,7 @@ next_insert(char *text, int pos, bool questionmarks,
bool std_strings)
 }

 static bool
-ecpg_type_infocache_push(struct ECPGtype_information_cache **cache, int
oid, enum ARRAY_TYPE isarray, int lineno)
+ecpg_type_infocache_push(struct ECPGtype_information_cache **cache, Oid
oid, enum ARRAY_TYPE isarray, int lineno)
 {
        struct ECPGtype_information_cache *new_entry
        = (struct ECPGtype_information_cache *) ecpg_alloc(sizeof(struct
ECPGtype_information_cache), lineno);
@@ -161,7 +161,7 @@ ecpg_type_infocache_push(struct
ECPGtype_information_cache **cache, int oid, enu
 }

 static enum ARRAY_TYPE
-ecpg_is_type_an_array(int type, const struct statement *stmt, const struct
variable *var)
+ecpg_is_type_an_array(Oid type, const struct statement *stmt, const struct
variable *var)
 {
        char       *array_query;
        enum ARRAY_TYPE isarray = ECPG_ARRAY_NOT_SET;
@@ -267,7 +267,7 @@ ecpg_is_type_an_array(int type, const struct statement
*stmt, const struct varia
        if (array_query == NULL)
                return ECPG_ARRAY_ERROR;

-       sprintf(array_query, "select typlen from pg_type where oid=%d and
typelem<>0", type);
+       sprintf(array_query, "select typlen from pg_type where oid=%u and
typelem<>0", type);
        query = PQexec(stmt->connection->connection, array_query);
        ecpg_free(array_query);
        if (!ecpg_check_PQresult(query, stmt->lineno,
stmt->connection->connection, stmt->compat))
@@ -294,7 +294,7 @@ ecpg_is_type_an_array(int type, const struct statement
*stmt, const struct varia
                return ECPG_ARRAY_ERROR;

        ecpg_type_infocache_push(&(stmt->connection->cache_head), type,
isarray, stmt->lineno);
-       ecpg_log("ecpg_is_type_an_array on line %d: type (%d); C (%d); array
(%s)\n", stmt->lineno, type, var->type, ECPG_IS_ARRAY(isarray) ? "yes" :
"no");
+       ecpg_log("ecpg_is_type_an_array on line %d: type (%u); C (%d); array
(%s)\n", stmt->lineno, type, var->type, ECPG_IS_ARRAY(isarray) ? "yes" :
"no");
        return isarray;
 }
```





pgsql-bugs by date:

Previous
From: Alexander Lakhin
Date:
Subject: Re: BUG #18943: Return value of a function 'xmlBufferCreate' isdereferenced at xpath.c:177 without checking for NUL
Next
From: Michael Paquier
Date:
Subject: Re: BUG #18943: Return value of a function 'xmlBufferCreate' isdereferenced at xpath.c:177 without checking for NUL