[PATCH] D42020: Correct ctype(3) functions with NLS on NetBSD

Kamil Rytarowski via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Fri Jan 12 16:39:48 PST 2018


krytarowski created this revision.
krytarowski added reviewers: vitalybuka, dvyukov, joerg.
krytarowski added a project: Sanitizers.
Herald added a subscriber: kubamracek.

The setlocale(3) function reloads the ctype(3) arrays from
external files. This happens behind the scenes in the internals
of libc (citrus library, runes functions etc).

ctype(3) functions like isspace(3) can be provided with two
variations on NetBSD: inlined or via a global symbol in libc:

  #if defined(_NETBSD_SOURCE) && !defined(_CTYPE_NOINLINE) && \
      !defined(__cplusplus)
  #include <sys/ctype_inline.h>
  #else
  #include <sys/ctype_bits.h>
  #endif

The in-lined versions are de-facto array lookup operations.

  #define isspace(c)      ((int)((_ctype_tab_ + 1)[(c)] & _CTYPE_S))

After setting setlocale(3) the ctype(3) arrays (_ctype_tab_,
_toupper_tab_, _tolower_tab_) are reload behind the scenes
and they are required to be marked as initialized.

Set them initialized inside the common setlocale(3) interceptor.

The arrays are of size of 267 elements: 0..256 + 1 (EOF).

This corrects errors on NetBSD/amd64 in applications
prebuilt with MSan.

Sponsored by <The NetBSD Foundation>


Repository:
  rL LLVM

https://reviews.llvm.org/D42020

Files:
  lib/sanitizer_common/sanitizer_common_interceptors.inc


Index: lib/sanitizer_common/sanitizer_common_interceptors.inc
===================================================================
--- lib/sanitizer_common/sanitizer_common_interceptors.inc
+++ lib/sanitizer_common/sanitizer_common_interceptors.inc
@@ -107,6 +107,10 @@
 #define times __times13
 #define wait3 __wait350
 #define wait4 __wait450
+// ctype(3) arrays
+extern const unsigned short *_ctype_tab_;
+extern const short *_toupper_tab_;
+extern const short *_tolower_tab_;
 #endif
 
 // Platform-specific options.
@@ -3164,7 +3168,15 @@
   if (locale)
     COMMON_INTERCEPTOR_READ_RANGE(ctx, locale, REAL(strlen)(locale) + 1);
   char *res = REAL(setlocale)(category, locale);
-  if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);
+  if (res) {
+    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);
+#if SANITIZER_NETBSD
+    // Valid array indices: -1 (EOF), 0, 1, .. 255
+    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, _ctype_tab_, 257 * sizeof(short));
+    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, _toupper_tab_, 257 * sizeof(short));
+    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, _tolower_tab_, 257 * sizeof(short));
+#endif
+  }
   return res;
 }
 


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D42020.129731.patch
Type: text/x-patch
Size: 1183 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20180113/c062259d/attachment.bin>


More information about the llvm-commits mailing list