Bug 243195

Summary: [libc] setlocale(LC_COLLATE, "...") causes segmentation fault after certain number of calls
Product: Base System Reporter: Koichi Murase <myoga.murase>
Component: binAssignee: Mark Johnston <markj>
Status: Closed FIXED    
Severity: Affects Some People CC: cem, markj, myoga.murase
Priority: ---    
Version: 12.1-RELEASE   
Hardware: Any   
OS: Any   

Description Koichi Murase 2020-01-08 18:30:57 UTC
I'm running FreeBSD 12.1-RELEASE in VirtualBox on Windows 10.

  $ uname -a
  FreeBSD vm-freebsd 12.1-RELEASE FreeBSD 12.1-RELEASE r354233 GENERIC  i386

The following reduced program results in a segmentation fault.

  $ cat test1.c
  #include <locale.h>
  #include <stdio.h>

  int main(int argc, char** argv) {
    int i;

    if (argc != 2) return 2;
    printf("start\n");
    fflush(stdout);
    for (i = 0; i < 100000; i++) {
      setlocale(LC_COLLATE, argv[1]);
      setlocale(LC_COLLATE, "C");
    }
    printf("done\n");
    fflush(stdout);
    return 0;
  }
  $ gcc -o test1 test1.c
  $ ./test1 en_US.UTF-8
  start
  Segmentation fault
  $ ./test1 ja_JP.UTF-8
  start
  Segmentation fault
  $ ./test1 ja_JP.eucJP
  start
  Segmentation fault

The number of successful invocation of `setlocale' until the
segmentation fault is always the same for the same locale, but it is
different for different locales.  The segmentation fault is only
caused when the category LC_COLLATE is changed (through LC_COLLTE or
LC_ALL).  There are no problems with the other categories.

I suspect the implementation of `__collate_load_tables_l' in
`lib/libc/locale/collate.c'.  I'm not sure but maybe there is a memory
leak caused by missing `munmap'?

https://github.com/freebsd/freebsd/blob/b6fca3ee8065a5cfd3a36abfd7a2663eb5bfee7d/lib/libc/locale/collate.c#L184
Comment 1 Conrad Meyer freebsd_committer freebsd_triage 2020-01-08 19:20:02 UTC
I suspect you're correct.  There's another bug nearby, where the return value of mmap() is checked for NULL rather than MAP_FAILED.
Comment 2 Mark Johnston freebsd_committer freebsd_triage 2020-01-09 16:43:51 UTC
This should be fixed by https://reviews.freebsd.org/D23109
Comment 3 commit-hook freebsd_committer freebsd_triage 2020-01-09 20:49:34 UTC
A commit references this bug:

Author: markj
Date: Thu Jan  9 20:49:26 UTC 2020
New revision: 356569
URL: https://svnweb.freebsd.org/changeset/base/356569

Log:
  libc: Fix a few bugs in the xlocale collation code.

  - Fix checks for mmap() failures. [1]
  - Set the "map" and "maplen" fields of struct xlocale_collate so that
    the table destructor actually does something.
  - Free an already-mapped collation file before loading a new one into
    the global table.
  - Harmonize the prototype and definition of __collate_load_tables_l() by
    adding the "static" qualifier to the latter.

  PR:		243195
  Reported by:	cem [1]
  Reviewed by:	cem, yuripv
  MFC after:	1 week
  Sponsored by:	The FreeBSD Foundation
  Differential Revision:	https://reviews.freebsd.org/D23109

Changes:
  head/lib/libc/locale/collate.c
  head/lib/libc/locale/rune.c
Comment 4 commit-hook freebsd_committer freebsd_triage 2020-01-16 00:27:39 UTC
A commit references this bug:

Author: markj
Date: Thu Jan 16 00:26:53 UTC 2020
New revision: 356769
URL: https://svnweb.freebsd.org/changeset/base/356769

Log:
  MFC r356569:
  libc: Fix a few bugs in the xlocale collation code.

  PR:	243195

Changes:
_U  stable/12/
  stable/12/lib/libc/locale/collate.c
  stable/12/lib/libc/locale/rune.c
Comment 5 Mark Johnston freebsd_committer freebsd_triage 2020-01-16 00:29:37 UTC
Thank you for the report.