--- a/sys/sys/iconv.h 2026-10-11 03:03:02.905635940 +0000 +++ b/sys/sys/iconv.h 2026-10-11 03:03:14.385487644 +0000 @@ -125,6 +125,7 @@ const char * cp_from; const char * cp_to; void * cp_data; + int cp_datalen; /* size of cp_data in bytes */ struct iconv_converter_class * cp_dcp; struct iconv_cspair *cp_base; TAILQ_ENTRY(iconv_cspair) cp_link; --- a/sys/libiconv/iconv.c 2026-10-11 03:03:02.909635888 +0000 +++ b/sys/libiconv/iconv.c 2026-10-11 03:03:14.385487644 +0000 @@ -423,6 +423,7 @@ lockmgr(&iconv_lock, LK_RELEASE); return error; } + csp->cp_datalen = din.ia_datalen; if (din.ia_datalen) { csp->cp_data = kmalloc(din.ia_datalen, M_ICONVDATA, M_WAITOK); error = copyin(din.ia_data, csp->cp_data, din.ia_datalen); --- a/sys/libiconv/iconv_xlat16.c 2026-10-11 03:03:02.909635888 +0000 +++ b/sys/libiconv/iconv_xlat16.c 2026-10-11 03:03:14.385487644 +0000 @@ -56,13 +56,31 @@ struct iconv_cspair * d_csp; }; +#define XLAT16_IDXLEN (0x200 * sizeof(uint32_t *)) /* index array */ +#define XLAT16_BLKLEN (0x80 * sizeof(uint32_t)) /* one data block */ + static int iconv_xlat16_open(struct iconv_converter_class *dcp, struct iconv_cspair *csp, struct iconv_cspair *cspf, void **dpp) { struct iconv_xlat16 *dp; uint32_t *headp, **idxp; - int i; + int i, nnz; + + /* + * Do not trust the table layout: cp_data must be large enough to + * hold the index array plus one data block per non-NULL index. + */ + if (csp->cp_datalen < XLAT16_IDXLEN) + return (EINVAL); + nnz = 0; + idxp = (uint32_t **)csp->cp_data; + for (i = 0; i < 0x200; i++) { + if (*idxp++ != 0) + nnz++; + } + if (csp->cp_datalen < XLAT16_IDXLEN + nnz * XLAT16_BLKLEN) + return (EINVAL); dp = (struct iconv_xlat16 *)kobj_create((struct kobj_class*)dcp, M_ICONV, M_WAITOK); headp = (uint32_t *)((caddr_t)csp->cp_data + sizeof(dp->d_table)); --- a/sys/libiconv/iconv_xlat.c 2026-10-11 03:03:02.909635888 +0000 +++ b/sys/libiconv/iconv_xlat.c 2026-10-11 03:03:14.385487644 +0000 @@ -57,6 +57,10 @@ { struct iconv_xlat *dp; + /* the xlat table must cover all 256 byte values */ + if (csp->cp_datalen < 256) + return (EINVAL); + dp = (struct iconv_xlat *)kobj_create((struct kobj_class*)dcp, M_ICONV, M_WAITOK); dp->d_table = csp->cp_data; dp->d_csp = csp;