⬢ DragonFlyBSD Kernel Audit
DF-3130 / fix.diff
← back to finding ↓ download raw
--- a/sys/vfs/msdosfs/msdosfs_vfsops.c
+++ b/sys/vfs/msdosfs/msdosfs_vfsops.c
@@ -112,10 +112,21 @@ update_mp(struct mount *mp, struct msdosfs_args *argp)
 	pmp->pm_flags |= argp->flags & MSDOSFSMNT_MNTOPT;
 
 	if (pmp->pm_flags & MSDOSFSMNT_KICONV && msdosfs_iconv) {
+		/*
+		 * Close any handles left over from a previous mount or
+		 * remount before overwriting the pointers; without this
+		 * every MNT_UPDATE leaks four iconv converters.
+		 */
+		if (pmp->pm_w2u)
+			msdosfs_iconv->close(pmp->pm_w2u);
+		if (pmp->pm_u2w)
+			msdosfs_iconv->close(pmp->pm_u2w);
+		if (pmp->pm_u2d)
+			msdosfs_iconv->close(pmp->pm_u2d);
+		if (pmp->pm_d2u)
+			msdosfs_iconv->close(pmp->pm_d2u);
 		memcpy(cs_local, argp->cs_local, sizeof(cs_local));
 		memcpy(cs_dos, argp->cs_dos, sizeof(cs_dos));
 		kprintf("local: %s dos: %s\n",argp->cs_local, argp->cs_dos);
 		error = msdosfs_iconv->open(cs_local, ENCODING_UNICODE,
 					    &pmp->pm_w2u);