git: 2329d94e49d3 - releng/14.3 - iconv(3): Fix problems in various encodings
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Tue, 30 Jun 2026 17:20:43 UTC
The branch releng/14.3 has been updated by markj:
URL: https://cgit.FreeBSD.org/src/commit/?id=2329d94e49d3a2d6e4272513c4e6a794f82e6a20
commit 2329d94e49d3a2d6e4272513c4e6a794f82e6a20
Author: Taylor R Campbell <riastradh@NetBSD.org>
AuthorDate: 2026-06-22 21:15:25 +0000
Commit: Mark Johnston <markj@FreeBSD.org>
CommitDate: 2026-06-30 02:32:02 +0000
iconv(3): Fix problems in various encodings
Fix null pointer dereference with HZ8 encoding.
Fix output buffer overrun in UTF-7, VIQR, ZW encodings.
Approved by: so
Security: FreeBSD-SA-26:49.iconv
Security: CVE-2026-58081
Reviewed by: markj, kevans
Differential Revision: https://reviews.freebsd.org/D57947
---
lib/libiconv_modules/HZ/citrus_hz.c | 2 ++
lib/libiconv_modules/UTF7/citrus_utf7.c | 20 +++++++++++++++-----
lib/libiconv_modules/VIQR/citrus_viqr.c | 6 +++++-
lib/libiconv_modules/ZW/citrus_zw.c | 7 +++++--
4 files changed, 27 insertions(+), 8 deletions(-)
diff --git a/lib/libiconv_modules/HZ/citrus_hz.c b/lib/libiconv_modules/HZ/citrus_hz.c
index f12938a7dab8..db738b8f812e 100644
--- a/lib/libiconv_modules/HZ/citrus_hz.c
+++ b/lib/libiconv_modules/HZ/citrus_hz.c
@@ -262,6 +262,8 @@ _citrus_HZ_mbrtowc_priv(_HZEncodingInfo * __restrict ei,
tail = psenc->chlen = 0;
continue;
}
+ if (graphic == NULL)
+ break;
} else if (ch & 0x80) {
if (graphic != GR(psenc->inuse))
break;
diff --git a/lib/libiconv_modules/UTF7/citrus_utf7.c b/lib/libiconv_modules/UTF7/citrus_utf7.c
index f924366551f1..e7c6a0862c54 100644
--- a/lib/libiconv_modules/UTF7/citrus_utf7.c
+++ b/lib/libiconv_modules/UTF7/citrus_utf7.c
@@ -296,7 +296,7 @@ done:
static int
_citrus_UTF7_utf16tomb(_UTF7EncodingInfo * __restrict ei,
- char * __restrict s, size_t n __unused, uint16_t u16,
+ char * __restrict s, size_t n, uint16_t u16,
_UTF7State * __restrict psenc, size_t * __restrict nresult)
{
int bits, i;
@@ -336,6 +336,8 @@ _citrus_UTF7_utf16tomb(_UTF7EncodingInfo * __restrict ei,
psenc->ch[psenc->chlen++] = base64[i];
}
}
+ if (n < (size_t)psenc->chlen)
+ return (E2BIG);
memcpy(s, psenc->ch, psenc->chlen);
*nresult = psenc->chlen;
psenc->chlen = 0;
@@ -352,6 +354,8 @@ _citrus_UTF7_wcrtomb_priv(_UTF7EncodingInfo * __restrict ei,
uint16_t u16[2];
int err, i, len;
size_t nr, siz;
+ char buf[8], *bufp = buf;
+ _UTF7State psenc_save = *psenc;
u32 = (uint32_t)wchar;
if (u32 <= UTF16_MAX) {
@@ -367,14 +371,20 @@ _citrus_UTF7_wcrtomb_priv(_UTF7EncodingInfo * __restrict ei,
return (EILSEQ);
}
siz = 0;
+ if (n > sizeof(buf))
+ n = sizeof(buf);
for (i = 0; i < len; ++i) {
- err = _citrus_UTF7_utf16tomb(ei, s, n, u16[i], psenc, &nr);
- if (err != 0)
- return (err); /* XXX: state has been modified */
- s += nr;
+ err = _citrus_UTF7_utf16tomb(ei, bufp, n, u16[i], psenc, &nr);
+ if (err != 0) {
+ *nresult = (size_t)-1;
+ *psenc = psenc_save; /* restore state */
+ return (err);
+ }
+ bufp += nr;
n -= nr;
siz += nr;
}
+ memcpy(s, buf, siz);
*nresult = siz;
return (0);
diff --git a/lib/libiconv_modules/VIQR/citrus_viqr.c b/lib/libiconv_modules/VIQR/citrus_viqr.c
index 1747c0a1705e..c1e88f188aab 100644
--- a/lib/libiconv_modules/VIQR/citrus_viqr.c
+++ b/lib/libiconv_modules/VIQR/citrus_viqr.c
@@ -323,7 +323,11 @@ _citrus_VIQR_wcrtomb_priv(_VIQREncodingInfo * __restrict ei,
int ch = 0;
switch (psenc->chlen) {
- case 0: case 1:
+ case 0:
+ break;
+ case 1:
+ if (n-- < 1)
+ goto e2big;
break;
default:
return (EINVAL);
diff --git a/lib/libiconv_modules/ZW/citrus_zw.c b/lib/libiconv_modules/ZW/citrus_zw.c
index 93590e550952..c59064e65465 100644
--- a/lib/libiconv_modules/ZW/citrus_zw.c
+++ b/lib/libiconv_modules/ZW/citrus_zw.c
@@ -264,9 +264,12 @@ _citrus_ZW_wcrtomb_priv(_ZWEncodingInfo * __restrict ei __unused,
ch = (unsigned char)wc;
switch (psenc->charset) {
case NONE:
- if (ch == '\0' || ch == '\n')
+ if (ch == '\0' || ch == '\n') {
+ if (n < 1)
+ return (E2BIG);
+ n -= 1;
psenc->ch[psenc->chlen++] = ch;
- else {
+ } else {
if (n < 4)
return (E2BIG);
n -= 4;