Commit 32f628be authored by Tom Lane's avatar Tom Lane

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
parent f46edf47
......@@ -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';
......
......@@ -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)
......
......@@ -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';
......
......@@ -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);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment