Index: sys/fs/msdosfs/direntry.h =================================================================== --- sys/fs/msdosfs/direntry.h +++ sys/fs/msdosfs/direntry.h @@ -145,7 +145,7 @@ char *mbnambuf_flush(struct mbnambuf *nbp, struct dirent *dp); void mbnambuf_init(struct mbnambuf *nbp); -void mbnambuf_write(struct mbnambuf *nbp, char *name, int id); +int mbnambuf_write(struct mbnambuf *nbp, char *name, int id); int dos2unixfn(u_char dn[11], u_char *un, int lower, struct msdosfsmount *pmp); int unix2dosfn(const u_char *un, u_char dn[12], size_t unlen, u_int gen, Index: sys/fs/msdosfs/msdosfs_conv.c =================================================================== --- sys/fs/msdosfs/msdosfs_conv.c +++ sys/fs/msdosfs/msdosfs_conv.c @@ -634,6 +634,7 @@ u_int8_t *np, name[WIN_CHARS * 3 + 1]; u_int16_t code; int i; + int error; if ((wep->weCnt&WIN_CNT) > howmany(WIN_MAXLEN, WIN_CHARS) || !(wep->weCnt&WIN_CNT)) @@ -658,7 +659,10 @@ switch (code) { case 0: *np = '\0'; - mbnambuf_write(nbp, name, (wep->weCnt & WIN_CNT) - 1); + error = mbnambuf_write(nbp, name, + (wep->weCnt & WIN_CNT)- 1); + if (error != 0) + return (-1); return chksum; case '/': *np = '\0'; @@ -676,7 +680,10 @@ switch (code) { case 0: *np = '\0'; - mbnambuf_write(nbp, name, (wep->weCnt & WIN_CNT) - 1); + error = mbnambuf_write(nbp, name, + (wep->weCnt & WIN_CNT) - 1); + if (error != 0) + return (-1); return chksum; case '/': *np = '\0'; @@ -694,7 +701,10 @@ switch (code) { case 0: *np = '\0'; - mbnambuf_write(nbp, name, (wep->weCnt & WIN_CNT) - 1); + error = mbnambuf_write(nbp, name, + (wep->weCnt & WIN_CNT) - 1); + if (error != 0) + return (-1); return chksum; case '/': *np = '\0'; @@ -708,7 +718,9 @@ cp += 2; } *np = '\0'; - mbnambuf_write(nbp, name, (wep->weCnt & WIN_CNT) - 1); + error = mbnambuf_write(nbp, name, (wep->weCnt & WIN_CNT) - 1); + if (error != 0) + return (-1); return chksum; } @@ -1005,7 +1017,7 @@ * This only penalizes portions of substrings that contain more than * WIN_CHARS bytes when they are first encountered. */ -void +int mbnambuf_write(struct mbnambuf *nbp, char *name, int id) { char *slot; @@ -1016,7 +1028,7 @@ printf("msdosfs: non-decreasing id: id %d, last id %d\n", id, nbp->nb_last_id); #endif - return; + return (EINVAL); } /* Will store this substring in a WIN_CHARS-aligned slot. */ @@ -1027,17 +1039,25 @@ #ifdef MSDOSFS_DEBUG printf("msdosfs: file name length %zu too large\n", newlen); #endif - return; + return (ENOMEM); } /* Shift suffix upwards by the amount length exceeds WIN_CHARS. */ if (count > WIN_CHARS && nbp->nb_len != 0) + { + if (((id * WIN_CHARS) + count + nbp->nb_len) > + sizeof(nbp->nb_buf)) + return (ENOMEM); + bcopy(slot + WIN_CHARS, slot + count, nbp->nb_len); + } /* Copy in the substring to its slot and update length so far. */ bcopy(name, slot, count); nbp->nb_len = newlen; nbp->nb_last_id = id; + + return (0); } /*