NetBSD-Bugs archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
lib/58631: libc: missing compile-time checks of mbstate_t usage
>Number: 58631
>Category: lib
>Synopsis: libc: missing compile-time checks of mbstate_t usage
>Confidential: no
>Severity: serious
>Priority: medium
>Responsible: lib-bug-people
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Sat Aug 24 13:00:00 +0000 2024
>Originator: Taylor R Campbell
>Release: current
>Organization:
The NetMBS Foundation_t
>Environment:
>Description:
The new mbrtoc8/16/32 and c8/16/32rtomb functions combine
(a) a four-byte buffer for UTF-8/16/32 code units (and possibly some padding), with
(b) an arbitrary locale-dependent mbstate_t for wcrtomb_l or mbrtowc_l conversion,
in a single caller-allocated mbstate_t object.
This requires the locale-dependent conversion logic to use no more than sizeof(mbstate_t) - offsetof(struct mbrtocNstate, mbs) bytes of storage in the mbstate_t.
Empirically, I have found that our Citrus modules don't use more than 36 bytes of mbstate_t by adding
__CTASSERT(sizeof(_ENCODING_STATE) <= 36);
to citrus_ctype_template.h, and since mbstate_t is 128 bytes long (and needs certainly no more than 64-byte alignment, more likely 8-byte at most on any architecture), we're safe for now.
But the state actually used by Citrus modules could change (and I may have missed something else that is stuffed into an mbstate_t). So this requirement needs to be asserted somewhere, and it needs to be matched up to cNrtomb/mbrtocN.
>How-To-Repeat:
code inspection
>Fix:
A cursory first draft for experiment, not fit for commit:
diff -r cf7a8f9687ea lib/libc/citrus/citrus_ctype_template.h
--- a/lib/libc/citrus/citrus_ctype_template.h Sat Aug 24 07:24:34 2024 +0000
+++ b/lib/libc/citrus/citrus_ctype_template.h Sat Aug 24 12:54:58 2024 +0000
@@ -511,6 +511,9 @@ int
__CTASSERT(alignof(_ENCODING_STATE) <= alignof(int) ||
alignof(_ENCODING_STATE) <= alignof(void *));
+/* Ensure we have enough buffer space for mbrtocN(3) and cNrtomb(3) */
+__CTASSERT(sizeof(_ENCODING_STATE) <= 36);
+
static int
_FUNCNAME(ctype_init)(void ** __restrict cl,
void * __restrict var, size_t lenvar, size_t lenps)
diff -r cf7a8f9687ea lib/libc/locale/c32rtomb.h
--- a/lib/libc/locale/c32rtomb.h Sat Aug 24 07:24:34 2024 +0000
+++ b/lib/libc/locale/c32rtomb.h Sat Aug 24 12:54:58 2024 +0000
@@ -34,7 +34,7 @@ struct c32rtombstate {
* XXX This needs to match the maximum size of any conversion
* state actually used by wcrtomb_l.
*/
- char dummy;
+ char dummy[96];
};
#endif /* LIB_LIBC_LOCALE_C32RTOMB_H_ */
diff -r cf7a8f9687ea lib/libc/locale/mbrtoc32.h
--- a/lib/libc/locale/mbrtoc32.h Sat Aug 24 07:24:34 2024 +0000
+++ b/lib/libc/locale/mbrtoc32.h Sat Aug 24 12:54:58 2024 +0000
@@ -34,7 +34,7 @@ struct mbrtoc32state {
* XXX This needs to match the maximum size of any conversion
* state actually used by mbrtowc_l.
*/
- char dummy;
+ char dummy[96];
};
#endif /* LIB_LIBC_LOCALE_MBRTOC32_H_ */
Home |
Main Index |
Thread Index |
Old Index