diff options
author | Andreas Schwab <schwab@suse.de> | 2021-01-06 11:03:44 +0530 |
---|---|---|
committer | Andreas K. Huettel <dilfridge@gentoo.org> | 2021-01-07 05:01:43 +0200 |
commit | 3aeafc6569203a733cde82699a4f5d06240d85d5 (patch) | |
tree | 379290e994ffceff85677ab9f8f41376a19e7ddc | |
parent | alpha: Provide wait4 for static library [BZ #27150] (diff) | |
download | glibc-3aeafc6569203a733cde82699a4f5d06240d85d5.tar.gz glibc-3aeafc6569203a733cde82699a4f5d06240d85d5.tar.bz2 glibc-3aeafc6569203a733cde82699a4f5d06240d85d5.zip |
Fix buffer overrun in EUC-KR conversion module (bz #24973)gentoo/glibc-2.32-6
The byte 0xfe as input to the EUC-KR conversion denotes a user-defined
area and is not allowed. The from_euc_kr function used to skip two bytes
when told to skip over the unknown designation, potentially running over
the buffer end.
(cherry picked from commit ee7a3144c9922808181009b7b3e50e852fb4999b)
(cherry picked from commit 0d9793e82a19bcef10ef7d73a26cd44b7ad30753)
-rw-r--r-- | iconvdata/Makefile | 3 | ||||
-rw-r--r-- | iconvdata/bug-iconv13.c | 53 | ||||
-rw-r--r-- | iconvdata/euc-kr.c | 6 | ||||
-rw-r--r-- | iconvdata/ksc5601.h | 6 |
4 files changed, 59 insertions, 9 deletions
diff --git a/iconvdata/Makefile b/iconvdata/Makefile index 4ec2741cdc..85009f3390 100644 --- a/iconvdata/Makefile +++ b/iconvdata/Makefile @@ -73,7 +73,8 @@ modules.so := $(addsuffix .so, $(modules)) ifeq (yes,$(build-shared)) tests = bug-iconv1 bug-iconv2 tst-loading tst-e2big tst-iconv4 bug-iconv4 \ tst-iconv6 bug-iconv5 bug-iconv6 tst-iconv7 bug-iconv8 bug-iconv9 \ - bug-iconv10 bug-iconv11 bug-iconv12 tst-iconv-big5-hkscs-to-2ucs4 + bug-iconv10 bug-iconv11 bug-iconv12 tst-iconv-big5-hkscs-to-2ucs4 \ + bug-iconv13 ifeq ($(have-thread-library),yes) tests += bug-iconv3 endif diff --git a/iconvdata/bug-iconv13.c b/iconvdata/bug-iconv13.c new file mode 100644 index 0000000000..87aaff398e --- /dev/null +++ b/iconvdata/bug-iconv13.c @@ -0,0 +1,53 @@ +/* bug 24973: Test EUC-KR module + Copyright (C) 2020 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <https://www.gnu.org/licenses/>. */ + +#include <errno.h> +#include <iconv.h> +#include <stdio.h> +#include <support/check.h> + +static int +do_test (void) +{ + iconv_t cd = iconv_open ("UTF-8//IGNORE", "EUC-KR"); + TEST_VERIFY_EXIT (cd != (iconv_t) -1); + + /* 0xfe (->0x7e : row 94) and 0xc9 (->0x49 : row 41) are user-defined + areas, which are not allowed and should be skipped over due to + //IGNORE. The trailing 0xfe also is an incomplete sequence, which + should be checked first. */ + char input[4] = { '\xc9', '\xa1', '\0', '\xfe' }; + char *inptr = input; + size_t insize = sizeof (input); + char output[4]; + char *outptr = output; + size_t outsize = sizeof (output); + + /* This used to crash due to buffer overrun. */ + TEST_VERIFY (iconv (cd, &inptr, &insize, &outptr, &outsize) == (size_t) -1); + TEST_VERIFY (errno == EINVAL); + /* The conversion should produce one character, the converted null + character. */ + TEST_VERIFY (sizeof (output) - outsize == 1); + + TEST_VERIFY_EXIT (iconv_close (cd) != -1); + + return 0; +} + +#include <support/test-driver.c> diff --git a/iconvdata/euc-kr.c b/iconvdata/euc-kr.c index b0d56cf3ee..1045bae926 100644 --- a/iconvdata/euc-kr.c +++ b/iconvdata/euc-kr.c @@ -80,11 +80,7 @@ euckr_from_ucs4 (uint32_t ch, unsigned char *cp) \ if (ch <= 0x9f) \ ++inptr; \ - /* 0xfe(->0x7e : row 94) and 0xc9(->0x59 : row 41) are \ - user-defined areas. */ \ - else if (__builtin_expect (ch == 0xa0, 0) \ - || __builtin_expect (ch > 0xfe, 0) \ - || __builtin_expect (ch == 0xc9, 0)) \ + else if (__glibc_unlikely (ch == 0xa0)) \ { \ /* This is illegal. */ \ STANDARD_FROM_LOOP_ERR_HANDLER (1); \ diff --git a/iconvdata/ksc5601.h b/iconvdata/ksc5601.h index d3eb3a4ff8..f5cdc72797 100644 --- a/iconvdata/ksc5601.h +++ b/iconvdata/ksc5601.h @@ -50,15 +50,15 @@ ksc5601_to_ucs4 (const unsigned char **s, size_t avail, unsigned char offset) unsigned char ch2; int idx; + if (avail < 2) + return 0; + /* row 94(0x7e) and row 41(0x49) are user-defined area in KS C 5601 */ if (ch < offset || (ch - offset) <= 0x20 || (ch - offset) >= 0x7e || (ch - offset) == 0x49) return __UNKNOWN_10646_CHAR; - if (avail < 2) - return 0; - ch2 = (*s)[1]; if (ch2 < offset || (ch2 - offset) <= 0x20 || (ch2 - offset) >= 0x7f) return __UNKNOWN_10646_CHAR; |