https://bugs.exim.org/show_bug.cgi?id=2794
--- Comment #9 from Thomas Tempelmann <tempelmann@???> ---
Done.
Assuming this is line 3330:
char buffer[FNBUFSIZ];
Then please rename "buffer" into "childpath" for better readability.
Then insert right after 3352 ("sprintf(..."):
#if 1 // <-- replace with test for Linux and BSD (macOS/Darwin)
// prevent endless recursion due to a symlink pointing to a parent dir
(Bug 2794)
char resolvedpath[PATH_MAX];
if (realpath(childpath, resolvedpath) == NULL)
continue; // this path is invalid - we can skip processing this
BOOL isSame = strcmp(pathname, resolvedpath) == 0;
if (isSame)
continue; // we have a recursion
strlcat(resolvedpath, "/", sizeof(resolvedpath));
size_t rlen = strlen(resolvedpath);
BOOL contained = strncmp(pathname, resolvedpath, rlen) == 0;
if (contained)
continue; // we have a recursion
resolvedpath[rlen-1] = 0; // removes the added "/"
strlcpy(childpath, resolvedpath, sizeof(childpath));
#endif
I've tested this to work successfully on macOS with my screwed-up symlink.
The tricky part is to tell whether the resolved path is pointing back to where
we already were.
With the first strcmp() I check whether it equals the parent current directory
path. This assumes, though, that "pathname" is also already resolved - but if
the user passed an unresolved path that points to itself, this recursion
detection will fail the first time, but then, in the recursion, the paths will
be the same (because I replace childpath with the resolved path further down)
and thus the recursion will be stopped. You could just as well also resolve the
path at the top of the function, but that's wasteful, IMO.
The second strcmp then checks of the resolved path exists as a the current
path's parent or their parent. I do this by adding a "/" to the resolved path
so that I do not mismatch the case where the resolved is "/a/b" and the parent
is "/a/b2".
Hope that helps.
--
You are receiving this mail because:
You are on the CC list for the bug.