From 32f628be74d8ab43423ca7913b81f7eb21b312d4 Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Thu, 28 May 2015 12:17:22 -0400 Subject: [PATCH] Fix assorted inconsistencies in our calls of readlink(). Ensure that we null-terminate the result string (one place in pg_rewind). Be paranoid about out-of-range results from readlink() (should not happen, but there is no good reason for some call sites to be careful about it and others not). Consistently use the whole buffer, not sometimes one byte less. Ensure we emit an appropriate errcode() in all cases. Spell the error messages the same way. The only serious bug here is the missing null-termination in pg_rewind, which is new code, so no need for a back-patch. Abhijit Menon-Sen and Tom Lane --- src/backend/replication/basebackup.c | 3 ++- src/backend/storage/file/fd.c | 9 ++++----- src/backend/utils/adt/misc.c | 8 +++++--- src/bin/pg_rewind/copy_fetch.c | 17 +++++++---------- 4 files changed, 18 insertions(+), 19 deletions(-) diff --git a/src/backend/replication/basebackup.c b/src/backend/replication/basebackup.c index fa29624667..1e86e4c57b 100644 --- a/src/backend/replication/basebackup.c +++ b/src/backend/replication/basebackup.c @@ -1028,7 +1028,8 @@ sendDir(char *path, int basepathlen, bool sizeonly, List *tablespaces, pathbuf))); if (rllen >= sizeof(linkpath)) ereport(ERROR, - (errmsg("symbolic link \"%s\" target is too long", + (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED), + errmsg("symbolic link \"%s\" target is too long", pathbuf))); linkpath[rllen] = '\0'; diff --git a/src/backend/storage/file/fd.c b/src/backend/storage/file/fd.c index 68d43c66b6..78aade98d1 100644 --- a/src/backend/storage/file/fd.c +++ b/src/backend/storage/file/fd.c @@ -2517,18 +2517,17 @@ walkdir(char *path, void (*action) (char *fname, bool isdir)) int len; struct stat lst; - len = readlink(subpath, linkpath, sizeof(linkpath) - 1); + len = readlink(subpath, linkpath, sizeof(linkpath)); if (len < 0) ereport(ERROR, (errcode_for_file_access(), errmsg("could not read symbolic link \"%s\": %m", subpath))); - - if (len >= sizeof(linkpath) - 1) + if (len >= sizeof(linkpath)) ereport(ERROR, - (errmsg("symbolic link \"%s\" target is too long", + (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED), + errmsg("symbolic link \"%s\" target is too long", subpath))); - linkpath[len] = '\0'; if (lstat(linkpath, &lst) == 0) diff --git a/src/backend/utils/adt/misc.c b/src/backend/utils/adt/misc.c index de68cdddf1..c0495d955c 100644 --- a/src/backend/utils/adt/misc.c +++ b/src/backend/utils/adt/misc.c @@ -374,11 +374,13 @@ pg_tablespace_location(PG_FUNCTION_ARGS) rllen = readlink(sourcepath, targetpath, sizeof(targetpath)); if (rllen < 0) ereport(ERROR, - (errmsg("could not read symbolic link \"%s\": %m", + (errcode_for_file_access(), + errmsg("could not read symbolic link \"%s\": %m", sourcepath))); - else if (rllen >= sizeof(targetpath)) + if (rllen >= sizeof(targetpath)) ereport(ERROR, - (errmsg("symbolic link \"%s\" target is too long", + (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED), + errmsg("symbolic link \"%s\" target is too long", sourcepath))); targetpath[rllen] = '\0'; diff --git a/src/bin/pg_rewind/copy_fetch.c b/src/bin/pg_rewind/copy_fetch.c index 9e317a2c7c..c92744ca77 100644 --- a/src/bin/pg_rewind/copy_fetch.c +++ b/src/bin/pg_rewind/copy_fetch.c @@ -112,19 +112,16 @@ recurse_dir(const char *datadir, const char *parentpath, { #if defined(HAVE_READLINK) || defined(WIN32) char link_target[MAXPGPATH]; - ssize_t len; + int len; - len = readlink(fullpath, link_target, sizeof(link_target) - 1); - if (len == -1) - pg_fatal("readlink() failed on \"%s\": %s\n", + len = readlink(fullpath, link_target, sizeof(link_target)); + if (len < 0) + pg_fatal("could not read symbolic link \"%s\": %s\n", fullpath, strerror(errno)); - - if (len == sizeof(link_target) - 1) - { - /* path was truncated */ - pg_fatal("symbolic link \"%s\" target path too long\n", + if (len >= sizeof(link_target)) + pg_fatal("symbolic link \"%s\" target is too long\n", fullpath); - } + link_target[len] = '\0'; callback(path, FILE_TYPE_SYMLINK, 0, link_target); -- 2.40.0