From 9e03b903e377c75a60cbbb89ed78955769a1c804 Mon Sep 17 00:00:00 2001 From: Jose Luis Duran Date: Thu, 13 Oct 2022 12:51:27 -0300 Subject: [PATCH] strfmon: Avoid an out-of-bounds access Avoid an out-of-bounds access when trying to set the space_char using an international currency format (%i) and the C/POSIX locale. The current code tries to read the SPACE from int_curr_symbol[3]: currency_symbol = strdup(lc->int_curr_symbol); space_char = *(currency_symbol+3); But on C/POSIX locales, int_curr_symbol is empty. Three implementations have been examined: NetBSD[1], Darwin[2], and Illumos[3]. Only NetBSD has fixed it[4]. Darwin and NetBSD also trim the mandatory final SPACE character after reading it. Locale Format Darwin/NetBSD FreeBSD/Illumos en_US.UTF-8 [%i] [USD123.45] [USD 123.45] fr_FR.UTF-8 [%i] [123,45 EUR] [123,45 EUR ] This commit only fixes the out-of-bounds access. [1]: https://github.com/NetBSD/src/blob/trunk/lib/libc/stdlib/strfmon.c [2]: https://opensource.apple.com/source/Libc/Libc-1439.141.1/stdlib/NetBSD/strfmon.c.auto.html [3]: https://github.com/illumos/illumos-gate/blob/master/usr/src/lib/libc/port/locale/strfmon.c [4]: https://github.com/NetBSD/src/commit/3d7b5d498aa9609f2bc9ece9c734c5f493a8e239 Reviewed by: kib PR: 267282 Github PR: #619 MFC after: 1 week --- lib/libc/stdlib/strfmon.c | 5 +++-- lib/libc/tests/stdlib/strfmon_test.c | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/lib/libc/stdlib/strfmon.c b/lib/libc/stdlib/strfmon.c index fbb1f79a87d..2526ab8fd8b 100644 --- a/lib/libc/stdlib/strfmon.c +++ b/lib/libc/stdlib/strfmon.c @@ -239,8 +239,9 @@ vstrfmon_l(char * __restrict s, size_t maxsize, locale_t loc, free(currency_symbol); if (flags & USE_INTL_CURRENCY) { currency_symbol = strdup(lc->int_curr_symbol); - if (currency_symbol != NULL) - space_char = *(currency_symbol+3); + if (currency_symbol != NULL && + strlen(currency_symbol) > 3) + space_char = currency_symbol[3]; } else currency_symbol = strdup(lc->currency_symbol); diff --git a/lib/libc/tests/stdlib/strfmon_test.c b/lib/libc/tests/stdlib/strfmon_test.c index 3e77a4f5290..dc328e974bb 100644 --- a/lib/libc/tests/stdlib/strfmon_test.c +++ b/lib/libc/tests/stdlib/strfmon_test.c @@ -197,7 +197,7 @@ ATF_TC_BODY(strfmon_international_currency_code, tc) } tests[] = { { "en_US.UTF-8", "[USD 123.45]" }, /* XXX */ { "de_DE.UTF-8", "[123,45 EUR ]" }, /* XXX */ - { "C", "[123.45]" }, /* XXX OOB access */ + { "C", "[123.45]" }, }; size_t i; char actual[100]; -- 2.45.0