Skip to content

Commit

Permalink
Fix: crash on failure to set locale
Browse files Browse the repository at this point in the history
setlocale() can fail, returning NULL, if the user has an invalid (or
missing) locale set in the LANG environment variable.

In my case, this happens when using VS Code's integrated terminal to
launch a fuse-based filesystem. A bug (fix upcoming) results in VS Code
setting an invalid locale.

iconv_help() currently passes the return value of setlocale(...)
directly to strdup() without checking if it is NULL, resulting in a
crash.

To reproduce, simply set LANG="something_invalid" and call
fuse_lib_help().

Stack trace when the process receives `SIGSEGV`:

(gdb) bt
 #0  0x00007fabd0fcc4b5 in __strlen_avx2 () from /usr/lib/libc.so.6
 libfuse#1  0x00007fabd0ef9233 in strdup () from /usr/lib/libc.so.6
 libfuse#2  0x00007fabd13b8128 in iconv_help () at ../lib/modules/iconv.c:641
 libfuse#3  0x00007fabd13b81a8 in iconv_opt_proc (data=0x55580a6ee850, arg=0x55580a6edfb0 "-h", key=0, outargs=0x7ffeeb1a8ec8) at ../lib/modules/iconv.c:658
 libfuse#4  0x00007fabd13af7d5 in call_proc (ctx=0x7ffeeb1a8ea0, arg=0x55580a6edfb0 "-h", key=0, iso=0) at ../lib/fuse_opt.c:161
 libfuse#5  0x00007fabd13afaf1 in process_opt (ctx=0x7ffeeb1a8ea0, opt=0x7fabd13c3d40 <iconv_opts>, sep=0, arg=0x55580a6edfb0 "-h", iso=0) at ../lib/fuse_opt.c:233
 libfuse#6  0x00007fabd13afd5a in process_gopt (ctx=0x7ffeeb1a8ea0, arg=0x55580a6edfb0 "-h", iso=0) at ../lib/fuse_opt.c:285
 libfuse#7  0x00007fabd13b0117 in process_one (ctx=0x7ffeeb1a8ea0, arg=0x55580a6edfb0 "-h") at ../lib/fuse_opt.c:368
 libfuse#8  0x00007fabd13b0190 in opt_parse (ctx=0x7ffeeb1a8ea0) at ../lib/fuse_opt.c:379
 libfuse#9  0x00007fabd13b03d3 in fuse_opt_parse (args=0x7ffeeb1a8f70, data=0x55580a6ee850, opts=0x7fabd13c3d40 <iconv_opts>, proc=0x7fabd13b8186 <iconv_opt_proc>)
    at ../lib/fuse_opt.c:414
 libfuse#10 0x00007fabd13b8226 in iconv_new (args=0x7ffeeb1a8f70, next=0x0) at ../lib/modules/iconv.c:680
 libfuse#11 0x00007fabd13a5627 in print_module_help (name=0x7fabd13b9e1c "iconv", fac=0x7fabd13d48e0 <fuse_module_iconv_factory>) at ../lib/fuse.c:4692
 libfuse#12 0x00007fabd13a56aa in fuse_lib_help (args=0x7ffeeb1a9238) at ../lib/fuse.c:4721

iconv_help() is modified to print an error when setlocale() fails.
It then carries on printing the iconv module's help.

Reading setlocale(3), it seems that the strdup() of the result was
not necessary.

Signed-off-by: Jérémie Galarneau <jeremie.galarneau@gmail.com>
  • Loading branch information
jgalar committed Jul 4, 2020
1 parent 7471156 commit cea3988
Showing 1 changed file with 10 additions and 4 deletions.
14 changes: 10 additions & 4 deletions lib/modules/iconv.c
Expand Up @@ -638,10 +638,16 @@ static const struct fuse_opt iconv_opts[] = {

static void iconv_help(void)
{
char *old = strdup(setlocale(LC_CTYPE, ""));
char *charmap = strdup(nl_langinfo(CODESET));
setlocale(LC_CTYPE, old);
free(old);
char *charmap;
const char *old = setlocale(LC_CTYPE, "");

charmap = strdup(nl_langinfo(CODESET));
if (old) {
setlocale(LC_CTYPE, old);
} else {
perror("setlocale");
}

printf(
" -o from_code=CHARSET original encoding of file names (default: UTF-8)\n"
" -o to_code=CHARSET new encoding of the file names (default: %s)\n",
Expand Down

0 comments on commit cea3988

Please sign in to comment.