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:
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)
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.
Sounds reasonable.
(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!
(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.
Also not a security issue.
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)
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.
FEDORA-2022-35fc4f5632 has been submitted as an update to Fedora 36. https://bodhi.fedoraproject.org/updates/FEDORA-2022-35fc4f5632
FEDORA-2022-9e02608a2f has been submitted as an update to Fedora 35. https://bodhi.fedoraproject.org/updates/FEDORA-2022-9e02608a2f
FEDORA-2022-35fc4f5632 has been pushed to the Fedora 36 testing repository. Soon you'll be able to install the update with the following command: `sudo dnf upgrade --enablerepo=updates-testing --advisory=FEDORA-2022-35fc4f5632` You can provide feedback for this update here: https://bodhi.fedoraproject.org/updates/FEDORA-2022-35fc4f5632 See also https://fedoraproject.org/wiki/QA:Updates_Testing for more information on how to test updates.
FEDORA-2022-9e02608a2f has been pushed to the Fedora 35 testing repository. Soon you'll be able to install the update with the following command: `sudo dnf upgrade --enablerepo=updates-testing --advisory=FEDORA-2022-9e02608a2f` You can provide feedback for this update here: https://bodhi.fedoraproject.org/updates/FEDORA-2022-9e02608a2f See also https://fedoraproject.org/wiki/QA:Updates_Testing for more information on how to test updates.
FEDORA-2022-35fc4f5632 has been pushed to the Fedora 36 stable repository. If problem still persists, please make note of it in this bug report.
FEDORA-2022-9e02608a2f has been pushed to the Fedora 35 stable repository. If problem still persists, please make note of it in this bug report.