kiconvtool
Purpose
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.
Usage
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
Examples
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.
- 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.
- Here's how I call kiconvtool:
- 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
Memory statistics
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
Bugs & possible problems
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.
rc.script
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"
TODO
- More testing
- More use cases for examples (udf and samba mounts, different locales)
- Manpage
- Try to solve case problem in kernel iconv
Where to get
Available in ports: sysutils/kiconvtool