On FreeBSD, it's possible to allow plain users to mount filesystems without using su or sudo. This is enabled via vfs.usermount sysctl. However, if file name conversion is used when mounting a filesystem, in most cases mount will fail with `mount_XXX: XXX_iconv: Operation not permitted denied' error. This is caused by the fact that character set conversion tables need to be loaded into kernel, but, apart from mounting, that's not allowed to plain users, because charset tables are large enough to initiate a denial of service by filling kernel memory with many tables.

This utility allows you to load only specific charset tables into kernel, so usermounts with file name conversions won't fail and in the same time it's not possible to bring the system down by filling kernel memory.

kiconvtool [-vhm] [local:foreign ...] [-l local ...]
           [-f foreign ...] [-p local:foreign ...] ...

Arguments:

  • -h display help
  • -v be verbose (report every action)
  • -l specify one or more local charsets to load
  • -f specify one or more foreign charsets to load
  • -p specify one or more charset pairs to load
  • -m display kernel memory usage statistics for iconv data

Those are based on my own kiconvtool usage patterns. Actually, it may be non-trivial to determine which charsets you actually need for your case, as mount won't print which charset it tries to load (and fails). But it should be sufficient to base on your locale charset as local, and common charsets for your country+some UTF charsets for foreign.

  1. My locale is KOI8-R and I need to mount USB flash with msdosfs. Mount options I use are: -L=ru_RU.KOI8-R -D=CP866 Here's how I call kiconvtool:
# kiconvtool -l KOI8-R -f UTF-16BE CP866

KOI8-R is for my locale, CP866 is used in legacy 8.3 msdosfs file names and UTF-16BE is used for long names.

  1. I want to mount CD-ROM with Russian file names:
# mount_cd9660 -C KOI8-R /dev/acd0 ~/mnt/cdrom

ISO9660 only uses unicode, so I only need:

# kiconvtool -l KOI8-R -f UTF-16BE

You can use kiconvtool -m to get memory statistics on loaded charset tables. Here's what you get after loading those 2 pairs for msdosfs:

# kiconvtool -l KOI8-R -f UTF-16BE CP866 -m
4 allocations, 90112 bytes

Another way to get those values is vmstat -m | grep iconv_data

The main bug is not in kiconvtool itself, but in kernel iconv implementation: charset names are case sensitive for kernel. This means the following: for mounting CDROMS with, say -C koi8-r you need to load koi8-r charset, and for mounting with -C KOI8-R you will need KOI8-R charset. While actually the same, those koi8-r and KOI8-R are distinct for kernel, they will take twice the memory and you won't be able to mount with -C koi8-r if you loaded just KOI8-R.

The best idea is to use all uppercase charset names. So check your scripts, fstab etc. to have charsets in the same case.

Also, make sure that you have iconv modules either loaded on startup or compiled into kernel. For msdosfs, for example, you'll need either

msdosfs_iconv_load="YES"

in your /boot/loader.conf or

options   LIBICONV
options   CD9660_ICONV

in your kernel.

There's also rc.d script provided with kiconvtool to preload charset tables on system startup. It supports following variables set in /etc/rc.conf:

  • kiconv_preload set to “YES” to enable running kiconvtool on startup
  • kiconv_local_charsets space separated list of local charsets
  • kiconv_foreign_charsets space separated list of foreign charsets
  • kiconv_charset_pairs space separated list of additional charset pairs

Example:

kiconv_preload="YES"
kiconv_local_charsets="KOI8-R"
kiconv_foreign_charsets="CP866 UTF-16BE"
  • More testing
  • More use cases for examples (udf and samba mounts, different locales)
  • Manpage
  • Try to solve case problem in kernel iconv
  • dmitrymarakasov/kiconvtool.txt
  • Last modified: 2018/03/19 01:33
  • by MarkLinimon