[PATCH] iconv: Fix iconv functions not following symlinks [BZ #32339]
Adhemerval Zanella Netto
adhemerval.zanella@linaro.org
Wed Jun 18 16:41:19 GMT 2025
On 16/06/25 06:59, avinal.xlvii@gmail.com wrote:
> From: Avinal Kumar <avinal.xlvii@gmail.com>
>
> On some file systems iconv do not follow symlinks. This happens because
> read_conf_file() function's directory traversal loop reject symbolic
> links and then lstat64() call do not follow symlinks.
>
> This commit fixes the directory traversal loop to accept symbolic links
> and then follow the link using stat64().
>
> Signed-off-by: Avinal Kumar <avinal.xlvii@gmail.com>
> ---
> As per discussion in BZ #32339, these changes should fix the issue. I need help
> testing it. It would be helpful if John can please test this on the particular
> system mentioned in the bug report. Looking forward for comments.
LGTM, I was wondering how hard would be to create a testcase. We have
--nostdlib, so it would a matter to create a temporary directory with a
configuration and a symlink, and check if the resulting cache has the
symlink config (which I think it would be most hard part).
> ---
> iconv/gconv_parseconfdir.h | 8 +++++---
> 1 file changed, 5 insertions(+), 3 deletions(-)
>
> diff --git a/iconv/gconv_parseconfdir.h b/iconv/gconv_parseconfdir.h
> index a7ebfd80cc..31f8f1c421 100644
> --- a/iconv/gconv_parseconfdir.h
> +++ b/iconv/gconv_parseconfdir.h
> @@ -33,9 +33,10 @@
> # define closedir __closedir
> # define mempcpy __mempcpy
> # define struct_stat64 struct __stat64_t64
> -# define lstat64 __lstat64_time64
> +# define stat64_impl __stat64_time64
> # define feof_unlocked __feof_unlocked
> #else
> +# define stat64_impl stat64
> # define struct_stat64 struct stat64
> #endif
>
> @@ -151,7 +152,8 @@ gconv_parseconfdir (const char *prefix, const char *dir, size_t dir_len)
> struct dirent64 *ent;
> while ((ent = readdir64 (confdir)) != NULL)
> {
> - if (ent->d_type != DT_REG && ent->d_type != DT_UNKNOWN)
> + if (ent->d_type != DT_REG && ent->d_type != DT_UNKNOWN
> + && ent->d_type != DT_LNK)
> continue;
>
> size_t len = strlen (ent->d_name);
> @@ -166,7 +168,7 @@ gconv_parseconfdir (const char *prefix, const char *dir, size_t dir_len)
> continue;
>
> if (ent->d_type != DT_UNKNOWN
> - || (lstat64 (conf, &st) != -1 && S_ISREG (st.st_mode)))
> + || (stat64_impl (conf, &st) != -1 && S_ISREG (st.st_mode)))
> found |= read_conf_file (conf, dir, dir_len);
>
> free (conf);
More information about the Libc-alpha
mailing list