public inbox for libc-alpha@sourceware.org
 help / color / mirror / Atom feed
* [PATCH v2] iconvconfig: Fix multiple issues
@ 2021-06-25  9:01 Siddhesh Poyarekar
  2021-06-25  9:05 ` Florian Weimer
  0 siblings, 1 reply; 4+ messages in thread
From: Siddhesh Poyarekar @ 2021-06-25  9:01 UTC (permalink / raw)
  To: libc-alpha; +Cc: schwab, fweimer

It was noticed on big-endian systems that msgfmt would fail with the
following error:

msgfmt: gconv_builtin.c:70: __gconv_get_builtin_trans: Assertion `cnt < sizeof (map) / sizeof (map[0])' failed.
Aborted (core dumped)

This is only seen on installed systems because it was due to a
corrupted gconv-modules.cache.  iconvconfig had the following issues
(it was specifically freeing fulldir that caused this issue, but other
cleanups are also needed) that this patch fixes.

- Add prefix only if dir starts with '/'
- Use asprintf instead of mempcpy so that the directory string is NULL
  terminated
- Make a copy of the directory reference in new_module so that fulldir
  can be freed within the same scope in handle_dir.
---
 iconv/Makefile      |  2 +-
 iconv/iconvconfig.c | 24 +++++++++---------------
 2 files changed, 10 insertions(+), 16 deletions(-)

diff --git a/iconv/Makefile b/iconv/Makefile
index a9b267c851..07d77c9eca 100644
--- a/iconv/Makefile
+++ b/iconv/Makefile
@@ -33,7 +33,7 @@ vpath %.c ../locale/programs ../intl
 iconv_prog-modules = iconv_charmap charmap charmap-dir linereader \
 		     dummy-repertoire simple-hash xstrdup xmalloc \
 		     record-status
-iconvconfig-modules = strtab xmalloc hash-string
+iconvconfig-modules = strtab xmalloc xasprintf xstrdup hash-string
 extra-objs	   = $(iconv_prog-modules:=.o) $(iconvconfig-modules:=.o)
 CFLAGS-iconv_prog.c += -I../locale/programs
 CFLAGS-iconv_charmap.c += -I../locale/programs
diff --git a/iconv/iconvconfig.c b/iconv/iconvconfig.c
index e69334d71c..783b2bbdbb 100644
--- a/iconv/iconvconfig.c
+++ b/iconv/iconvconfig.c
@@ -250,6 +250,7 @@ static const char gconv_module_ext[] = MODULE_EXT;
 
 
 #include <programs/xmalloc.h>
+#include <programs/xasprintf.h>
 
 
 /* C string table handling.  */
@@ -519,11 +520,12 @@ module_compare (const void *p1, const void *p2)
 /* Create new module record.  */
 static void
 new_module (const char *fromname, size_t fromlen, const char *toname,
-	    size_t tolen, const char *directory,
+	    size_t tolen, const char *dir_in,
 	    const char *filename, size_t filelen, int cost, size_t need_ext)
 {
   struct module *new_module;
-  size_t dirlen = strlen (directory) + 1;
+  size_t dirlen = strlen (dir_in) + 1;
+  const char *directory = xstrdup (dir_in);
   char *tmp;
   void **inserted;
 
@@ -654,20 +656,10 @@ handle_dir (const char *dir)
   size_t dirlen = strlen (dir);
   bool found = false;
 
-  /* Add the prefix before sending it off to the parser.  */
-  char *fulldir = xmalloc (prefix_len + dirlen + 2);
-  char *cp = mempcpy (mempcpy (fulldir, prefix, prefix_len), dir, dirlen);
+  char *fulldir = xasprintf ("%s%s%s", dir[0] == '/' ? prefix : "",
+			     dir, dir[dirlen - 1] != '/' ? "/" : "");
 
-  if (dir[dirlen - 1] != '/')
-    {
-      *cp++ = '/';
-      *cp = '\0';
-      dirlen++;
-    }
-
-  found = gconv_parseconfdir (fulldir, dirlen + prefix_len);
-
-  free (fulldir);
+  found = gconv_parseconfdir (fulldir, strlen (fulldir));
 
   if (!found)
     {
@@ -679,6 +671,8 @@ handle_dir (const char *dir)
 	     "configuration files with names ending in .conf.");
     }
 
+  free (fulldir);
+
   return found ? 0 : 1;
 }
 
-- 
2.31.1


^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH v2] iconvconfig: Fix multiple issues
  2021-06-25  9:01 [PATCH v2] iconvconfig: Fix multiple issues Siddhesh Poyarekar
@ 2021-06-25  9:05 ` Florian Weimer
  2021-06-25  9:07   ` Siddhesh Poyarekar
  0 siblings, 1 reply; 4+ messages in thread
From: Florian Weimer @ 2021-06-25  9:05 UTC (permalink / raw)
  To: Siddhesh Poyarekar; +Cc: libc-alpha, schwab

* Siddhesh Poyarekar:

> @@ -519,11 +520,12 @@ module_compare (const void *p1, const void *p2)
>  /* Create new module record.  */
>  static void
>  new_module (const char *fromname, size_t fromlen, const char *toname,
> -	    size_t tolen, const char *directory,
> +	    size_t tolen, const char *dir_in,
>  	    const char *filename, size_t filelen, int cost, size_t need_ext)
>  {
>    struct module *new_module;
> -  size_t dirlen = strlen (directory) + 1;
> +  size_t dirlen = strlen (dir_in) + 1;
> +  const char *directory = xstrdup (dir_in);

Sorry, why is this copy needed?

Thanks,
Florian


^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH v2] iconvconfig: Fix multiple issues
  2021-06-25  9:05 ` Florian Weimer
@ 2021-06-25  9:07   ` Siddhesh Poyarekar
  2021-06-27 17:13     ` Florian Weimer
  0 siblings, 1 reply; 4+ messages in thread
From: Siddhesh Poyarekar @ 2021-06-25  9:07 UTC (permalink / raw)
  To: Florian Weimer; +Cc: schwab, libc-alpha

On 6/25/21 2:35 PM, Florian Weimer via Libc-alpha wrote:
> * Siddhesh Poyarekar:
> 
>> @@ -519,11 +520,12 @@ module_compare (const void *p1, const void *p2)
>>   /* Create new module record.  */
>>   static void
>>   new_module (const char *fromname, size_t fromlen, const char *toname,
>> -	    size_t tolen, const char *directory,
>> +	    size_t tolen, const char *dir_in,
>>   	    const char *filename, size_t filelen, int cost, size_t need_ext)
>>   {
>>     struct module *new_module;
>> -  size_t dirlen = strlen (directory) + 1;
>> +  size_t dirlen = strlen (dir_in) + 1;
>> +  const char *directory = xstrdup (dir_in);
> 
> Sorry, why is this copy needed?

That's the fulldir reference that goes from here into the symtab and so 
on.  Later once the handle_dir function returns and the cache file is 
being written out, this pointer is referenced and by then it has already 
been freed.

Siddhesh

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH v2] iconvconfig: Fix multiple issues
  2021-06-25  9:07   ` Siddhesh Poyarekar
@ 2021-06-27 17:13     ` Florian Weimer
  0 siblings, 0 replies; 4+ messages in thread
From: Florian Weimer @ 2021-06-27 17:13 UTC (permalink / raw)
  To: Siddhesh Poyarekar; +Cc: schwab, libc-alpha

* Siddhesh Poyarekar:

> On 6/25/21 2:35 PM, Florian Weimer via Libc-alpha wrote:
>> * Siddhesh Poyarekar:
>> 
>>> @@ -519,11 +520,12 @@ module_compare (const void *p1, const void *p2)
>>>   /* Create new module record.  */
>>>   static void
>>>   new_module (const char *fromname, size_t fromlen, const char *toname,
>>> -	    size_t tolen, const char *directory,
>>> +	    size_t tolen, const char *dir_in,
>>>   	    const char *filename, size_t filelen, int cost, size_t need_ext)
>>>   {
>>>     struct module *new_module;
>>> -  size_t dirlen = strlen (directory) + 1;
>>> +  size_t dirlen = strlen (dir_in) + 1;
>>> +  const char *directory = xstrdup (dir_in);
>> Sorry, why is this copy needed?
>
> That's the fulldir reference that goes from here into the symtab and
> so on.  Later once the handle_dir function returns and the cache file
> is being written out, this pointer is referenced and by then it has
> already been freed.

I see, it's returned to the caller via new_module->directory.

Apparently we do not free modules, so this doesn't add a new leak.

Patch looks okay to me then.

Thanks,
Florian


^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2021-06-27 17:13 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-06-25  9:01 [PATCH v2] iconvconfig: Fix multiple issues Siddhesh Poyarekar
2021-06-25  9:05 ` Florian Weimer
2021-06-25  9:07   ` Siddhesh Poyarekar
2021-06-27 17:13     ` Florian Weimer

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).