From b5fbad71edc1e4afc6ae3e9c43dc920b10bb76d6 Mon Sep 17 00:00:00 2001 From: Tatsuo Ishii Date: Sat, 3 Aug 2024 14:30:33 +0900 Subject: [PATCH] Use psprintf() instead of snprintf(). 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 | 66 ++++++++++++++++++++++---------- 1 file changed, 45 insertions(+), 21 deletions(-) diff --git a/src/query_cache/pool_memqcache.c b/src/query_cache/pool_memqcache.c index 6526cb9f1..5c4b30470 100644 --- a/src/query_cache/pool_memqcache.c +++ b/src/query_cache/pool_memqcache.c @@ -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 -- 2.39.5