diff options
author | Florian Weimer <fweimer@redhat.com> | 2019-07-31 11:43:59 +0200 |
---|---|---|
committer | Florian Weimer <fweimer@redhat.com> | 2019-07-31 11:43:59 +0200 |
commit | 0bfddfc9444ed6154da7e70bae6a1b4809b88c93 (patch) | |
tree | 3b6a738aeebc8f5b4cb0937c0995ce5c8d74e62a /libio/iofclose.c | |
parent | c86b8e7579ac2c4a1f1f70a56715580ed77b4a79 (diff) | |
download | glibc-0bfddfc9444ed6154da7e70bae6a1b4809b88c93.zip glibc-0bfddfc9444ed6154da7e70bae6a1b4809b88c93.tar.gz glibc-0bfddfc9444ed6154da7e70bae6a1b4809b88c93.tar.bz2 |
iconv: Revert steps array reference counting changes
The changes introduce a memory leak for gconv steps arrays whose
first element is an internal conversion, which has a fixed
reference count which is not decremented. As a result, after the
change in commit 50ce3eae5ba304650459d4441d7d246a7cefc26f, the steps
array is never freed, resulting in an unbounded memory leak.
This reverts commit 50ce3eae5ba304650459d4441d7d246a7cefc26f
("gconv: Check reference count in __gconv_release_cache
[BZ #24677]") and commit 7e740ab2e7be7d83b75513aa406e0b10875f7f9c
("libio: Fix gconv-related memory leak [BZ #24583]"). It
reintroduces bug 24583. (Bug 24677 was just a regression caused by
the second commit.)
Diffstat (limited to 'libio/iofclose.c')
-rw-r--r-- | libio/iofclose.c | 15 |
1 files changed, 6 insertions, 9 deletions
diff --git a/libio/iofclose.c b/libio/iofclose.c index c03c6cf..8a80dd0 100644 --- a/libio/iofclose.c +++ b/libio/iofclose.c @@ -26,8 +26,8 @@ #include "libioP.h" #include <stdlib.h> +#include "../iconv/gconv_int.h" #include <shlib-compat.h> -#include <wcsmbs/wcsmbsload.h> int _IO_new_fclose (FILE *fp) @@ -60,14 +60,11 @@ _IO_new_fclose (FILE *fp) /* This stream has a wide orientation. This means we have to free the conversion functions. */ struct _IO_codecvt *cc = fp->_codecvt; - struct gconv_fcts conv = - { - .towc = cc->__cd_in.__cd.__steps, - .towc_nsteps = cc->__cd_in.__cd.__nsteps, - .tomb = cc->__cd_out.__cd.__steps, - .tomb_nsteps = cc->__cd_out.__cd.__nsteps, - }; - __wcsmbs_close_conv (&conv); + + __libc_lock_lock (__gconv_lock); + __gconv_release_step (cc->__cd_in.__cd.__steps); + __gconv_release_step (cc->__cd_out.__cd.__steps); + __libc_lock_unlock (__gconv_lock); } else { |