+++ This bug was initially created as a clone of Bug #2081583 +++ Description of problem: glibc iconv_open accesses memory past buffer. This might be a security issue. Version-Release number of selected component (if applicable): glibc-2.34-32.fc35.src.rpm How reproducible: Minimal reproduction: #include <iconv.h> int main(void) { iconv_t fd = iconv_open("UTF-8", "EUC-JP"); iconv_close(fd); return 0; } Steps to Reproduce: 1. Compile program 2. Run it with valgrind Actual results: ==185== Invalid read of size 8 ==185== at 0x40044C0: strncmp (strcmp.S:173) ==185== by 0x400A1AD: is_dst (dl-load.c:215) ==185== by 0x400B376: _dl_dst_count (dl-load.c:252) ==185== by 0x400B577: expand_dynamic_string_token (dl-load.c:394) ==185== by 0x400B6D7: fillin_rpath.isra.0 (dl-load.c:482) ==185== by 0x400B9C2: decompose_rpath (dl-load.c:653) ==185== by 0x400D8F2: _dl_map_object (dl-load.c:2124) ==185== by 0x40082A4: openaux (dl-deps.c:64) ==185== by 0x49EEA07: _dl_catch_exception (in /usr/lib64/libc.so.6) ==185== by 0x40086ED: _dl_map_object_deps (dl-deps.c:248) ==185== by 0x4011341: dl_open_worker_begin (dl-open.c:591) ==185== by 0x49EEA07: _dl_catch_exception (in /usr/lib64/libc.so.6) ==185== Address 0x4a63951 is 1 bytes inside a block of size 8 alloc'd ==185== at 0x484486F: malloc (vg_replace_malloc.c:381) ==185== by 0x40274CF: malloc (rtld-malloc.h:56) ==185== by 0x40274CF: strdup (strdup.c:42) ==185== by 0x400B954: decompose_rpath (dl-load.c:628) ==185== by 0x400D8F2: _dl_map_object (dl-load.c:2124) ==185== by 0x40082A4: openaux (dl-deps.c:64) ==185== by 0x49EEA07: _dl_catch_exception (in /usr/lib64/libc.so.6) ==185== by 0x40086ED: _dl_map_object_deps (dl-deps.c:248) ==185== by 0x4011341: dl_open_worker_begin (dl-open.c:591) ==185== by 0x49EEA07: _dl_catch_exception (in /usr/lib64/libc.so.6) ==185== by 0x4010A99: dl_open_worker (dl-open.c:777) ==185== by 0x49EEA07: _dl_catch_exception (in /usr/lib64/libc.so.6) ==185== by 0x4010E8E: _dl_open (dl-open.c:878) Expected results: No errors. Additional info: --- Additional comment from Aki Tuomi on 2022-05-04 05:38:51 UTC --- Full valgrind output showing the out of bounds access: ==185== Memcheck, a memory error detector ==185== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al. ==185== Using Valgrind-3.18.1 and LibVEX; rerun with -h for copyright info ==185== Command: ./test ==185== ==185== Invalid read of size 8 ==185== at 0x40044C0: strncmp (strcmp.S:173) ==185== by 0x400A1AD: is_dst (dl-load.c:215) ==185== by 0x400B376: _dl_dst_count (dl-load.c:252) ==185== by 0x400B577: expand_dynamic_string_token (dl-load.c:394) ==185== by 0x400B6D7: fillin_rpath.isra.0 (dl-load.c:482) ==185== by 0x400B9C2: decompose_rpath (dl-load.c:653) ==185== by 0x400D8F2: _dl_map_object (dl-load.c:2124) ==185== by 0x40082A4: openaux (dl-deps.c:64) ==185== by 0x49EEA07: _dl_catch_exception (in /usr/lib64/libc.so.6) ==185== by 0x40086ED: _dl_map_object_deps (dl-deps.c:248) ==185== by 0x4011341: dl_open_worker_begin (dl-open.c:591) ==185== by 0x49EEA07: _dl_catch_exception (in /usr/lib64/libc.so.6) ==185== Address 0x4a63951 is 1 bytes inside a block of size 8 alloc'd ==185== at 0x484486F: malloc (vg_replace_malloc.c:381) ==185== by 0x40274CF: malloc (rtld-malloc.h:56) ==185== by 0x40274CF: strdup (strdup.c:42) ==185== by 0x400B954: decompose_rpath (dl-load.c:628) ==185== by 0x400D8F2: _dl_map_object (dl-load.c:2124) ==185== by 0x40082A4: openaux (dl-deps.c:64) ==185== by 0x49EEA07: _dl_catch_exception (in /usr/lib64/libc.so.6) ==185== by 0x40086ED: _dl_map_object_deps (dl-deps.c:248) ==185== by 0x4011341: dl_open_worker_begin (dl-open.c:591) ==185== by 0x49EEA07: _dl_catch_exception (in /usr/lib64/libc.so.6) ==185== by 0x4010A99: dl_open_worker (dl-open.c:777) ==185== by 0x49EEA07: _dl_catch_exception (in /usr/lib64/libc.so.6) ==185== by 0x4010E8E: _dl_open (dl-open.c:878) ==185== ==185== Invalid read of size 8 ==185== at 0x40044C8: strncmp (strcmp.S:175) ==185== by 0x400A1AD: is_dst (dl-load.c:215) ==185== by 0x400B376: _dl_dst_count (dl-load.c:252) ==185== by 0x400B577: expand_dynamic_string_token (dl-load.c:394) ==185== by 0x400B6D7: fillin_rpath.isra.0 (dl-load.c:482) ==185== by 0x400B9C2: decompose_rpath (dl-load.c:653) ==185== by 0x400D8F2: _dl_map_object (dl-load.c:2124) ==185== by 0x40082A4: openaux (dl-deps.c:64) ==185== by 0x49EEA07: _dl_catch_exception (in /usr/lib64/libc.so.6) ==185== by 0x40086ED: _dl_map_object_deps (dl-deps.c:248) ==185== by 0x4011341: dl_open_worker_begin (dl-open.c:591) ==185== by 0x49EEA07: _dl_catch_exception (in /usr/lib64/libc.so.6) ==185== Address 0x4a63959 is 1 bytes after a block of size 8 alloc'd ==185== at 0x484486F: malloc (vg_replace_malloc.c:381) ==185== by 0x40274CF: malloc (rtld-malloc.h:56) ==185== by 0x40274CF: strdup (strdup.c:42) ==185== by 0x400B954: decompose_rpath (dl-load.c:628) ==185== by 0x400D8F2: _dl_map_object (dl-load.c:2124) ==185== by 0x40082A4: openaux (dl-deps.c:64) ==185== by 0x49EEA07: _dl_catch_exception (in /usr/lib64/libc.so.6) ==185== by 0x40086ED: _dl_map_object_deps (dl-deps.c:248) ==185== by 0x4011341: dl_open_worker_begin (dl-open.c:591) ==185== by 0x49EEA07: _dl_catch_exception (in /usr/lib64/libc.so.6) ==185== by 0x4010A99: dl_open_worker (dl-open.c:777) ==185== by 0x49EEA07: _dl_catch_exception (in /usr/lib64/libc.so.6) ==185== by 0x4010E8E: _dl_open (dl-open.c:878) ==185== ==185== Invalid read of size 8 ==185== at 0x40044C0: strncmp (strcmp.S:173) ==185== by 0x400A1AD: is_dst (dl-load.c:215) ==185== by 0x400B429: _dl_dst_substitute (dl-load.c:294) ==185== by 0x400B6D7: fillin_rpath.isra.0 (dl-load.c:482) ==185== by 0x400B9C2: decompose_rpath (dl-load.c:653) ==185== by 0x400D8F2: _dl_map_object (dl-load.c:2124) ==185== by 0x40082A4: openaux (dl-deps.c:64) ==185== by 0x49EEA07: _dl_catch_exception (in /usr/lib64/libc.so.6) ==185== by 0x40086ED: _dl_map_object_deps (dl-deps.c:248) ==185== by 0x4011341: dl_open_worker_begin (dl-open.c:591) ==185== by 0x49EEA07: _dl_catch_exception (in /usr/lib64/libc.so.6) ==185== by 0x4010A99: dl_open_worker (dl-open.c:777) ==185== Address 0x4a63951 is 1 bytes inside a block of size 8 alloc'd ==185== at 0x484486F: malloc (vg_replace_malloc.c:381) ==185== by 0x40274CF: malloc (rtld-malloc.h:56) ==185== by 0x40274CF: strdup (strdup.c:42) ==185== by 0x400B954: decompose_rpath (dl-load.c:628) ==185== by 0x400D8F2: _dl_map_object (dl-load.c:2124) ==185== by 0x40082A4: openaux (dl-deps.c:64) ==185== by 0x49EEA07: _dl_catch_exception (in /usr/lib64/libc.so.6) ==185== by 0x40086ED: _dl_map_object_deps (dl-deps.c:248) ==185== by 0x4011341: dl_open_worker_begin (dl-open.c:591) ==185== by 0x49EEA07: _dl_catch_exception (in /usr/lib64/libc.so.6) ==185== by 0x4010A99: dl_open_worker (dl-open.c:777) ==185== by 0x49EEA07: _dl_catch_exception (in /usr/lib64/libc.so.6) ==185== by 0x4010E8E: _dl_open (dl-open.c:878) ==185== ==185== Invalid read of size 8 ==185== at 0x40044C8: strncmp (strcmp.S:175) ==185== by 0x400A1AD: is_dst (dl-load.c:215) ==185== by 0x400B429: _dl_dst_substitute (dl-load.c:294) ==185== by 0x400B6D7: fillin_rpath.isra.0 (dl-load.c:482) ==185== by 0x400B9C2: decompose_rpath (dl-load.c:653) ==185== by 0x400D8F2: _dl_map_object (dl-load.c:2124) ==185== by 0x40082A4: openaux (dl-deps.c:64) ==185== by 0x49EEA07: _dl_catch_exception (in /usr/lib64/libc.so.6) ==185== by 0x40086ED: _dl_map_object_deps (dl-deps.c:248) ==185== by 0x4011341: dl_open_worker_begin (dl-open.c:591) ==185== by 0x49EEA07: _dl_catch_exception (in /usr/lib64/libc.so.6) ==185== by 0x4010A99: dl_open_worker (dl-open.c:777) ==185== Address 0x4a63959 is 1 bytes after a block of size 8 alloc'd ==185== at 0x484486F: malloc (vg_replace_malloc.c:381) ==185== by 0x40274CF: malloc (rtld-malloc.h:56) ==185== by 0x40274CF: strdup (strdup.c:42) ==185== by 0x400B954: decompose_rpath (dl-load.c:628) ==185== by 0x400D8F2: _dl_map_object (dl-load.c:2124) ==185== by 0x40082A4: openaux (dl-deps.c:64) ==185== by 0x49EEA07: _dl_catch_exception (in /usr/lib64/libc.so.6) ==185== by 0x40086ED: _dl_map_object_deps (dl-deps.c:248) ==185== by 0x4011341: dl_open_worker_begin (dl-open.c:591) ==185== by 0x49EEA07: _dl_catch_exception (in /usr/lib64/libc.so.6) ==185== by 0x4010A99: dl_open_worker (dl-open.c:777) ==185== by 0x49EEA07: _dl_catch_exception (in /usr/lib64/libc.so.6) ==185== by 0x4010E8E: _dl_open (dl-open.c:878) ==185== ==185== ==185== HEAP SUMMARY: ==185== in use at exit: 0 bytes in 0 blocks ==185== total heap usage: 24 allocs, 24 frees, 36,146 bytes allocated ==185== ==185== All heap blocks were freed -- no leaks are possible ==185== ==185== For lists of detected and suppressed errors, rerun with: -s ==185== ERROR SUMMARY: 4 errors from 4 contexts (suppressed: 0 from 0) --- Additional comment from Carlos O'Donell on 2022-05-06 00:46:05 UTC --- Adding DJ Delorie and Florian Weimer from my team to help with RCA. --- Additional comment from Florian Weimer on 2022-05-06 08:01:41 UTC --- As far as I can see, this overread in strncmp is just an optimization. The assembler code takes care of not crossing a cache line boundary. The memory allocation is 8 bytes for a string of length 7 ("$ORIGIN"). So it looks all good to me. It seems that valgrind lacks a redirect for strncmp in the dynamic loader. --- Additional comment from Aki Tuomi on 2022-05-06 12:15:01 UTC --- Sounds reasonable. --- Additional comment from Florian Weimer on 2022-05-06 12:21:53 UTC --- (In reply to Aki Tuomi from comment #4) > Sounds reasonable. I'll try to get this bug reclassified as non-security, and will reassign it to valgrind. Thanks for spotting this issue! --- Additional comment from Patrick Del Bello on 2022-05-06 20:28:45 UTC --- Removing security group as requested by Florian --- Additional comment from Siddhesh Poyarekar on 2022-05-09 03:31:02 UTC --- (In reply to Florian Weimer from comment #3) > It seems that valgrind lacks a redirect for strncmp in the dynamic loader. Reassigning to valgrind to let Mark figure out how to handle this. --- Additional comment from Siddhesh Poyarekar on 2022-05-09 03:32:01 UTC --- Also not a security issue. --- Additional comment from Mark Wielaard on 2022-05-13 11:45:45 UTC --- STRCMP is but STRNCMP isn't intercepted from ld.so. The following would do the trick (on x86_64 at least): diff --git a/shared/vg_replace_strmem.c b/shared/vg_replace_strmem.c index 3b42b3a87..df466f250 100644 --- a/shared/vg_replace_strmem.c +++ b/shared/vg_replace_strmem.c @@ -710,6 +710,7 @@ static inline void my_exit ( int x ) STRNCMP(VG_Z_LIBC_SONAME, __GI_strncmp) STRNCMP(VG_Z_LIBC_SONAME, __strncmp_sse2) STRNCMP(VG_Z_LIBC_SONAME, __strncmp_sse42) + STRNCMP(VG_Z_LD_LINUX_X86_64_SO_2, strncmp) #elif defined(VGO_freebsd) STRNCMP(VG_Z_LIBC_SONAME, strncmp) --- Additional comment from Mark Wielaard on 2022-05-13 23:34:16 UTC --- Fixed upstream and in rawhide. If this looks OK I'll add it to f36 and f35. See some more analysis in the upstream bug.
Since the problem described in this bug report should be resolved in a recent advisory, it has been closed with a resolution of ERRATA. For information on the advisory (valgrind bug fix and enhancement update), and where to find the updated files, follow the link below. If the solution does not work for you, open a new bug report. https://access.redhat.com/errata/RHBA-2022:8066