diff --git a/sys/vfs/msdosfs/msdosfs_conv.c b/sys/vfs/msdosfs/msdosfs_conv.c --- a/sys/vfs/msdosfs/msdosfs_conv.c +++ b/sys/vfs/msdosfs/msdosfs_conv.c @@ -1058,6 +1058,18 @@ memmove(slot + count, slot + WIN_CHARS, nbp->nb_len); } + /* + * Bound the absolute write position: the slot offset (id * WIN_CHARS) + * plus the substring length (count) must not exceed the buffer size. + * Without this, a malicious Win95 entry with weCnt&WIN_CNT == 20 (id=19) + * and all 13 name positions non-null makes us memcpy 13 bytes at + * nb_buf[247], overflowing nb_buf[256] by 4 bytes (ASCII) or 17 bytes + * (KICONV). The cumulative check above only bounds nb_len+count, not + * the absolute slot offset. + */ + if (id * WIN_CHARS + count > sizeof(nbp->nb_buf)) + return (ENAMETOOLONG); + /* Copy in the substring to its slot and update length so far. */ memcpy(slot, name, count); nbp->nb_len = newlen;