Use psprintf() instead of snprintf().
authorTatsuo Ishii <ishii@postgresql.org>
Sat, 3 Aug 2024 05:30:33 +0000 (14:30 +0900)
committerTatsuo Ishii <ishii@postgresql.org>
Sat, 3 Aug 2024 05:30:33 +0000 (14:30 +0900)
Previously fixed size buffers were used for snprintf in the file. It's
not appropriate to use snprintf here because the result string could
exceed the buffer size and it could lead to incomplete command or path
used after.

Backpatch-through: 4.1.

src/query_cache/pool_memqcache.c

index 6526cb9f1db43c644a1f26420b8f6baf1ef4a567..5c4b3047042dd23cae8f4c30a90815044e44ce2d 100644 (file)
@@ -3,7 +3,7 @@
  * pgpool: a language independent connection pool server for PostgreSQL
  * written by Tatsuo Ishii
  *
- * Copyright (c) 2003-2023     PgPool Global Development Group
+ * Copyright (c) 2003-2024     PgPool Global Development Group
  *
  * Permission to use, copy, modify, and distribute this software and
  * its documentation for any purpose and without fee is hereby
@@ -1412,6 +1412,9 @@ pool_get_dml_table_oid(int **oid)
        return oidbufp;
 }
 
+/*
+ * Extract table oids contained in memqcache_oiddir by database oid.
+ */
 static int
 pool_get_dropdb_table_oids(int **oids, int dboid)
 {
@@ -1422,14 +1425,15 @@ pool_get_dropdb_table_oids(int **oids, int dboid)
        int                     num_oids = 0;
        DIR                *dir;
        struct dirent *dp;
-       char            path[1024];
+       char            *path;
 
-       snprintf(path, sizeof(path), "%s/%d", pool_config->memqcache_oiddir, dboid);
+       path = psprintf("%s/%d", pool_config->memqcache_oiddir, dboid);
        if ((dir = opendir(path)) == NULL)
        {
                ereport(DEBUG1,
                                (errmsg("memcache: getting drop table oids"),
                                 errdetail("Failed to open dir: %s", path)));
+               pfree(path);
                return 0;
        }
 
@@ -1445,6 +1449,7 @@ pool_get_dropdb_table_oids(int **oids, int dboid)
                        if (tmp == NULL)
                        {
                                closedir(dir);
+                               pfree(path);
                                return 0;
                        }
                        rtn = tmp;
@@ -1454,6 +1459,7 @@ pool_get_dropdb_table_oids(int **oids, int dboid)
                num_oids++;
        }
 
+       pfree(path);
        closedir(dir);
        *oids = rtn;
 
@@ -1536,14 +1542,15 @@ pool_get_database_oid_from_dbname(char *dbname)
 {
        int                     dboid = 0;
        POOL_SELECT_RESULT *res;
-       char            query[1024];
+       char            *query;
 
        POOL_CONNECTION_POOL *backend;
 
        backend = pool_get_session_context(false)->backend;
 
-       snprintf(query, sizeof(query), DATABASE_TO_OID_QUERY, dbname);
+       query = psprintf(DATABASE_TO_OID_QUERY, dbname);
        do_query(MAIN(backend), query, &res, MAJOR(backend));
+       pfree(query);
 
        if (res->numrows != 1)
        {
@@ -1573,7 +1580,7 @@ pool_add_table_oid_map(POOL_CACHEKEY * cachekey, int num_table_oids, int *table_
 {
        char       *dir;
        int                     dboid;
-       char            path[1024];
+       char            *path;
        int                     i;
        int                     len;
 
@@ -1608,7 +1615,7 @@ pool_add_table_oid_map(POOL_CACHEKEY * cachekey, int num_table_oids, int *table_
                return;
        }
 
-       snprintf(path, sizeof(path), "%s/%d", dir, dboid);
+       path = psprintf("%s/%d", dir, dboid);
        if (mkdir(path, S_IREAD | S_IWRITE | S_IEXEC) == -1)
        {
                if (errno != EEXIST)
@@ -1616,9 +1623,11 @@ pool_add_table_oid_map(POOL_CACHEKEY * cachekey, int num_table_oids, int *table_
                        ereport(WARNING,
                                        (errmsg("memcache: adding table oid maps, failed to create directory:\"%s\"", path),
                                         errdetail("%m")));
+                       pfree(path);
                        return;
                }
        }
+       pfree(path);
 
        if (pool_is_shmem_cache())
        {
@@ -1639,12 +1648,13 @@ pool_add_table_oid_map(POOL_CACHEKEY * cachekey, int num_table_oids, int *table_
                /*
                 * Create or open each memqcache_oiddir/database_oid/table_oid
                 */
-               snprintf(path, sizeof(path), "%s/%d/%d", dir, dboid, oid);
+               path = psprintf("%s/%d/%d", dir, dboid, oid);
                if ((fd = open(path, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR)) == -1)
                {
                        ereport(WARNING,
                                        (errmsg("memcache: adding table oid maps, failed to open file:\"%s\"", path),
                                         errdetail("%m")));
+                       pfree(path);
                        return;
                }
 
@@ -1661,6 +1671,7 @@ pool_add_table_oid_map(POOL_CACHEKEY * cachekey, int num_table_oids, int *table_
                                         errdetail("%m")));
 
                        close(fd);
+                       pfree(path);
                        return;
                }
 
@@ -1713,6 +1724,7 @@ pool_add_table_oid_map(POOL_CACHEKEY * cachekey, int num_table_oids, int *table_
                                        (errmsg("memcache: adding table oid maps, failed seek on file:\"%s\"", path),
                                         errdetail("%m")));
                        close(fd);
+                       pfree(path);
                        return;
                }
 
@@ -1729,37 +1741,41 @@ pool_add_table_oid_map(POOL_CACHEKEY * cachekey, int num_table_oids, int *table_
                        return;
                }
                close(fd);
+               pfree(path);
        }
 }
 
 /*
- * Discard all oid maps at pgpool-II startup.
+ * Discard all oid maps at Pgpool-II startup.
  * This is necessary for shmem case.
  */
 void
 pool_discard_oid_maps(void)
 {
-       char            command[1024];
+       char            *command;
 
-       snprintf(command, sizeof(command), "/bin/rm -fr %s/[0-9]*",
-                        pool_config->memqcache_oiddir);
+       command = psprintf("/bin/rm -fr %s/[0-9]*",
+                                          pool_config->memqcache_oiddir);
        if (system(command) == -1)
                ereport(WARNING,
                                (errmsg("unable to execute command \"%s\"", command),
                                 errdetail("system() command failed with error \"%m\"")));
 
-
+       pfree(command);
 }
 
+/*
+ *  Discard all oid maps contained in database specified by dboid.
+ */
 void
 pool_discard_oid_maps_by_db(int dboid)
 {
-       char            command[1024];
+       char            *command;
 
        if (pool_is_shmem_cache())
        {
-               snprintf(command, sizeof(command), "/bin/rm -fr %s/%d/",
-                                pool_config->memqcache_oiddir, dboid);
+               command = psprintf("/bin/rm -fr %s/%d/",
+                                                  pool_config->memqcache_oiddir, dboid);
 
                ereport(DEBUG1,
                                (errmsg("memcache: discarding oid maps by db"),
@@ -1769,6 +1785,8 @@ pool_discard_oid_maps_by_db(int dboid)
                        ereport(WARNING,
                                        (errmsg("unable to execute command \"%s\"", command),
                                         errdetail("system() command failed with error \"%m\"")));
+
+               pfree(command);
        }
 }
 
@@ -1782,7 +1800,7 @@ static void
 pool_invalidate_query_cache(int num_table_oids, int *table_oid, bool unlinkp, int dboid)
 {
        char       *dir;
-       char            path[1024];
+       char            *path;
        int                     i;
        int                     len;
        POOL_CACHEKEY buf;
@@ -1820,7 +1838,7 @@ pool_invalidate_query_cache(int num_table_oids, int *table_oid, bool unlinkp, in
                }
        }
 
-       snprintf(path, sizeof(path), "%s/%d", dir, dboid);
+       path = psprintf("%s/%d", dir, dboid);
        if (mkdir(path, S_IREAD | S_IWRITE | S_IEXEC) == -1)
        {
                if (errno != EEXIST)
@@ -1828,6 +1846,7 @@ pool_invalidate_query_cache(int num_table_oids, int *table_oid, bool unlinkp, in
                        ereport(WARNING,
                                        (errmsg("memcache: invalidating query cache, failed to create directory:\"%s\"", path),
                                         errdetail("%m")));
+                       pfree(path);
                        return;
                }
        }
@@ -1851,7 +1870,7 @@ pool_invalidate_query_cache(int num_table_oids, int *table_oid, bool unlinkp, in
                /*
                 * Open each memqcache_oiddir/database_oid/table_oid
                 */
-               snprintf(path, sizeof(path), "%s/%d/%d", dir, dboid, oid);
+               path = psprintf("%s/%d/%d", dir, dboid, oid);
                if ((fd = open(path, O_RDONLY)) == -1)
                {
                        /*
@@ -1877,6 +1896,7 @@ pool_invalidate_query_cache(int num_table_oids, int *table_oid, bool unlinkp, in
                                        (errmsg("memcache: invalidating query cache, failed to lock file:\"%s\"", path),
                                         errdetail("%m")));
                        close(fd);
+                       pfree(path);
                        return;
                }
                for (;;)
@@ -1889,6 +1909,7 @@ pool_invalidate_query_cache(int num_table_oids, int *table_oid, bool unlinkp, in
                                                 errdetail("%m")));
 
                                close(fd);
+                               pfree(path);
                                return;
                        }
                        else if (sts == len)
@@ -1926,6 +1947,7 @@ pool_invalidate_query_cache(int num_table_oids, int *table_oid, bool unlinkp, in
                                ereport(WARNING,
                                                (errmsg("memcache: invalidating query cache, invalid data length:%d in file:\"%s\"", sts, path)));
                                close(fd);
+                               pfree(path);
                                return;
                        }
                        break;
@@ -1935,6 +1957,7 @@ pool_invalidate_query_cache(int num_table_oids, int *table_oid, bool unlinkp, in
                {
                        unlink(path);
                }
+               pfree(path);
                close(fd);
        }
 #ifdef SHMEMCACHE_DEBUG
@@ -2992,9 +3015,9 @@ pool_shmem_lock(POOL_MEMQ_LOCK_TYPE type)
 {
        if (memq_lock_fd == 0)
        {
-               char path[1024];
+               char *path;
 
-               snprintf(path, sizeof(path), "%s/%s", pool_config->logdir, QUERY_CACHE_LOCK_FILE);
+               path = psprintf("%s/%s", pool_config->logdir, QUERY_CACHE_LOCK_FILE);
                memq_lock_fd = open(path, O_CREAT | O_TRUNC | O_WRONLY, S_IRUSR | S_IWUSR);
                if (memq_lock_fd == -1)
                {
@@ -3002,6 +3025,7 @@ pool_shmem_lock(POOL_MEMQ_LOCK_TYPE type)
                                        (errmsg("Failed to open lock file for query cache \"%s\"", path),
                                         errdetail("%m")));
                }
+               pfree(path);
        }
 
 #ifdef LOCK_TRACE