Fix buffer overflows related to unchecked make_string().
authorPeter Eisentraut <peter_e@gmx.net>
Fri, 9 Jul 2004 18:50:51 +0000 (18:50 +0000)
committerPeter Eisentraut <peter_e@gmx.net>
Fri, 9 Jul 2004 18:50:51 +0000 (18:50 +0000)
connection.c
drvconn.c
execute.c
info.c
misc.c
misc.h

index dac2a514539b1e9b34633c3b767020611fd955c4..7c8de653abf23877ab42c4cd376621ec37aa3cad 100644 (file)
@@ -107,7 +107,7 @@ PGAPI_Connect(
 
    ci = &conn->connInfo;
 
-   make_string(szDSN, cbDSN, ci->dsn);
+   make_string(szDSN, cbDSN, ci->dsn, sizeof(ci->dsn));
 
    /* get the values for the DSN from the registry */
    memcpy(&ci->drivers, &globals, sizeof(globals));
@@ -120,8 +120,8 @@ PGAPI_Connect(
     * override values from DSN info with UID and authStr(pwd) This only
     * occurs if the values are actually there.
     */
-   make_string(szUID, cbUID, ci->username);
-   make_string(szAuthStr, cbAuthStr, ci->password);
+   make_string(szUID, cbUID, ci->username, sizeof(ci->username));
+   make_string(szAuthStr, cbAuthStr, ci->password, sizeof(ci->password));
 
    /* fill in any defaults */
    getDSNdefaults(ci);
index 0211eda93840a7f04976aeb464d46480d1ed63da..3ea1867d03af7ff629aa2904443db4f197b3a65c 100644 (file)
--- a/drvconn.c
+++ b/drvconn.c
@@ -95,7 +95,7 @@ PGAPI_DriverConnect(
    RETCODE     dialog_result;
 #endif
    RETCODE     result;
-   char        connStrIn[MAX_CONNECT_STRING];
+   char       *connStrIn;
    char        connStrOut[MAX_CONNECT_STRING];
    int         retval;
    char        salt[5];
@@ -112,7 +112,7 @@ PGAPI_DriverConnect(
        return SQL_INVALID_HANDLE;
    }
 
-   make_string(szConnStrIn, cbConnStrIn, connStrIn);
+   connStrIn = make_string(szConnStrIn, cbConnStrIn, NULL, 0);
 
 #ifdef FORCE_PASSWORD_DISPLAY
    mylog("**** PGAPI_DriverConnect: fDriverCompletion=%d, connStrIn='%s'\n", fDriverCompletion, connStrIn);
@@ -291,6 +291,9 @@ dialog:
 #endif /* FORCE_PASSWORD_DISPLAY */
 
 
+   if (connStrIn)
+       free(connStrIn);
+
    mylog("PGAPI_DriverConnect: returning %d\n", result);
    return result;
 }
index 7b3c87971a90bd1f5533c5184d44bcf443f042a1..83a9272b49d7180fe5319ac2d0d6fb2560c632c1 100644 (file)
--- a/execute.c
+++ b/execute.c
@@ -102,7 +102,7 @@ PGAPI_Prepare(HSTMT hstmt,
    if (!szSqlStr[0])
        self->statement = strdup("");
    else
-       self->statement = make_string(szSqlStr, cbSqlStr, NULL);
+       self->statement = make_string(szSqlStr, cbSqlStr, NULL, 0);
    if (!self->statement)
    {
        SC_set_error(self, STMT_NO_MEMORY_ERROR, "No memory available to store statement");
@@ -147,7 +147,7 @@ PGAPI_ExecDirect(
     * keep a copy of the un-parametrized statement, in case they try to
     * execute this statement again
     */
-   stmt->statement = make_string(szSqlStr, cbSqlStr, NULL);
+   stmt->statement = make_string(szSqlStr, cbSqlStr, NULL, 0);
    if (!stmt->statement)
    {
        SC_set_error(stmt, STMT_NO_MEMORY_ERROR, "No memory available to store statement");
@@ -787,7 +787,7 @@ PGAPI_NativeSql(
 
    mylog("%s: entering...cbSqlStrIn=%d\n", func, cbSqlStrIn);
 
-   ptr = (cbSqlStrIn == 0) ? "" : make_string(szSqlStrIn, cbSqlStrIn, NULL);
+   ptr = (cbSqlStrIn == 0) ? "" : make_string(szSqlStrIn, cbSqlStrIn, NULL, 0);
    if (!ptr)
    {
        CC_set_error(conn, CONN_NO_MEMORY_ERROR, "No memory available to store native sql string");
diff --git a/info.c b/info.c
index 9b7b3bf7ac229a711163eda2d30dc6b24361cdd6..a199fc4d33c072f8022644889982111772c0ef23 100644 (file)
--- a/info.c
+++ b/info.c
@@ -1397,7 +1397,7 @@ retry_public_schema:
    show_views = FALSE;
 
    /* make_string mallocs memory */
-   tableType = make_string(szTableType, cbTableType, NULL);
+   tableType = make_string(szTableType, cbTableType, NULL, 0);
    if (tableType)
    {
        strcpy(table_types, tableType);
@@ -2637,7 +2637,7 @@ PGAPI_Statistics(
     * only use the table name... the owner should be redundant, and we
     * never use qualifiers.
     */
-   table_name = make_string(szTableName, cbTableName, NULL);
+   table_name = make_string(szTableName, cbTableName, NULL, 0);
    if (!table_name)
    {
        SC_set_error(stmt, STMT_INTERNAL_ERROR, "No table name passed to PGAPI_Statistics.");
@@ -3033,7 +3033,8 @@ PGAPI_PrimaryKeys(
    char        tables_query[INFO_INQUIRY_LEN];
    char        attname[MAX_INFO_STRING];
    SDWORD      attname_len;
-   char        pktab[TABLE_NAME_STORAGE_LEN + 1], pkscm[TABLE_NAME_STORAGE_LEN + 1];
+   char       *pktab;
+   char        pkscm[TABLE_NAME_STORAGE_LEN + 1];
    Int2        result_cols;
    int         qno,
                qstart,
@@ -3090,9 +3091,8 @@ PGAPI_PrimaryKeys(
        internal_asis_type = INTERNAL_ASIS_TYPE;
 #endif /* UNICODE_SUPPORT */
 
-   pktab[0] = '\0';
-   make_string(szTableName, cbTableName, pktab);
-   if (pktab[0] == '\0')
+   pktab = make_string(szTableName, cbTableName, NULL, 0);
+   if (pktab == NULL || pktab[0] == '\0')
    {
        SC_set_error(stmt, STMT_INTERNAL_ERROR, "No Table specified to PGAPI_PrimaryKeys.");
        goto cleanup;
@@ -3257,6 +3257,9 @@ retry_public_schema:
    ret = SQL_SUCCESS;
 
 cleanup:
+   if (pktab)
+       free(pktab);
+
    /*
     * also, things need to think that this statement is finished so the
     * results can be retrieved.
@@ -3537,12 +3540,12 @@ PGAPI_ForeignKeys(
    char        trig_args[1024];
    char        upd_rule[TABLE_NAME_STORAGE_LEN],
                del_rule[TABLE_NAME_STORAGE_LEN];
-   char        pk_table_needed[TABLE_NAME_STORAGE_LEN + 1];
-char       fk_table_fetched[TABLE_NAME_STORAGE_LEN + 1];
-   char        fk_table_needed[TABLE_NAME_STORAGE_LEN + 1];
-char       pk_table_fetched[TABLE_NAME_STORAGE_LEN + 1];
+   char       *pk_table_needed;
+   char        fk_table_fetched[TABLE_NAME_STORAGE_LEN + 1];
+   char       *fk_table_needed;
+   char        pk_table_fetched[TABLE_NAME_STORAGE_LEN + 1];
    char        schema_needed[SCHEMA_NAME_STORAGE_LEN + 1];
-char       schema_fetched[SCHEMA_NAME_STORAGE_LEN + 1];
+   char        schema_fetched[SCHEMA_NAME_STORAGE_LEN + 1];
    char       *pkey_ptr,
               *pkey_text,
               *fkey_ptr,
@@ -3638,13 +3641,11 @@ char        schema_fetched[SCHEMA_NAME_STORAGE_LEN + 1];
 
    tbl_stmt = (StatementClass *) htbl_stmt;
 
-   pk_table_needed[0] = '\0';
-   fk_table_needed[0] = '\0';
    schema_needed[0] = '\0';
    schema_fetched[0] = '\0';
 
-   make_string(szPkTableName, cbPkTableName, pk_table_needed);
-   make_string(szFkTableName, cbFkTableName, fk_table_needed);
+   pk_table_needed = make_string(szPkTableName, cbPkTableName, NULL, 0);
+   fk_table_needed = make_string(szFkTableName, cbFkTableName, NULL, 0);
 
    conn = SC_get_conn(stmt);
 #ifdef UNICODE_SUPPORT
@@ -3658,7 +3659,7 @@ char      schema_fetched[SCHEMA_NAME_STORAGE_LEN + 1];
     * Case #2 -- Get the foreign keys in the specified table (fktab) that
     * refer to the primary keys of other table(s).
     */
-   if (fk_table_needed[0] != '\0')
+   if (fk_table_needed && fk_table_needed[0] != '\0')
    {
        mylog("%s: entering Foreign Key Case #2", func);
        if (conn->schema_support)
@@ -3864,7 +3865,7 @@ char      schema_fetched[SCHEMA_NAME_STORAGE_LEN + 1];
            mylog("Foreign Key Case#2: trig_nargs = %d, num_keys = %d\n", trig_nargs, num_keys);
 
            /* If there is a pk table specified, then check it. */
-           if (pk_table_needed[0] != '\0')
+           if (pk_table_needed && pk_table_needed[0] != '\0')
            {
                /* If it doesn't match, then continue */
                if (strcmp(pk_table_fetched, pk_table_needed))
@@ -4302,6 +4303,12 @@ char     schema_fetched[SCHEMA_NAME_STORAGE_LEN + 1];
    ret = SQL_SUCCESS;
 
 cleanup:
+   if (fk_table_needed)
+       free(fk_table_needed);
+   if (pk_table_needed)
+       free(pk_table_needed);
+
+
    /*
     * also, things need to think that this statement is finished so the
     * results can be retrieved.
diff --git a/misc.c b/misc.c
index 96cc94a4927e5dd65dd1a37a5c30d153a420599d..4589f19bf5847d3d7cf101c3738990b2e57353cd 100644 (file)
--- a/misc.c
+++ b/misc.c
@@ -259,14 +259,15 @@ strncpy_null(char *dst, const char *src, int len)
 /*------
  * Create a null terminated string (handling the SQL_NTS thing):
  *     1. If buf is supplied, place the string in there
- *        (assumes enough space) and return buf.
+ *        (at most bufsize-1 bytes) and return buf.
  *     2. If buf is not supplied, malloc space and return this string
+ *        (buflen is ignored in this case)
  *------
  */
 char *
-make_string(const char *s, int len, char *buf)
+make_string(const char *s, int len, char *buf, size_t bufsize)
 {
-   int         length;
+   unsigned int    length;
    char       *str;
 
    if (s && (len > 0 || (len == SQL_NTS && strlen(s) > 0)))
@@ -275,6 +276,8 @@ make_string(const char *s, int len, char *buf)
 
        if (buf)
        {
+           if (length >= bufsize)
+               length = bufsize - 1;
            strncpy_null(buf, s, length + 1);
            return buf;
        }
diff --git a/misc.h b/misc.h
index 58d6ee9d20ea8c23679d50b23f40681dd7e60c26..96c764112d74200c43e9823d2bd74a03781a4c02 100644 (file)
--- a/misc.h
+++ b/misc.h
@@ -119,7 +119,7 @@ int get_mylog(void);
 void       remove_newlines(char *string);
 char      *strncpy_null(char *dst, const char *src, int len);
 char      *trim(char *string);
-char      *make_string(const char *s, int len, char *buf);
+char      *make_string(const char *s, int len, char *buf, size_t bufsize);
 char      *make_lstring_ifneeded(ConnectionClass *, const char *s, int len, BOOL);
 char      *my_strcat(char *buf, const char *fmt, const char *s, int len);
 char      *schema_strcat(char *buf, const char *fmt, const char *s, int len,