bug-gnulib
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

getdelim: Work around buggy implementation on macOS 10.13


From: Bruno Haible
Subject: getdelim: Work around buggy implementation on macOS 10.13
Date: Mon, 17 Oct 2022 02:53:35 +0200

While testing a GNU sed snapshot on macOS 10.13, I see this test failure:

FAIL: testsuite/bug32082
========================

valgrind report for 'posix' test:
==================================
--85029-- run: /usr/bin/dsymutil 
"/Users/haible/devel/sed-4.8.39-23ea/build-64/./sed/sed"
--85029-- UNKNOWN mach_msg unhandled MACH_SEND_TRAILER option
--85029-- UNKNOWN mach_msg unhandled MACH_SEND_TRAILER option (repeated 2 times)
--85029-- UNKNOWN mach_msg unhandled MACH_SEND_TRAILER option (repeated 4 times)
--85029-- UNKNOWN mach_msg unhandled MACH_SEND_TRAILER option (repeated 8 times)
==85029== Invalid read of size 16
==85029==    at 0x100EE6A05: _platform_memchr$VARIANT$Base (in 
/usr/lib/system/libsystem_platform.dylib)
==85029==    by 0x100B7B0BD: getdelim (in /usr/lib/system/libsystem_c.dylib)
==85029==    by 0x10000B0BE: ck_getdelim (utils.c:254)
==85029==    by 0x1000090A9: read_file_line (execute.c:388)
==85029==    by 0x100008A12: read_pattern_space (execute.c:718)
==85029==    by 0x1000066DA: process_files (execute.c:1682)
==85029==    by 0x10000A5D9: main (sed.c:378)
==85029==  Address 0x1019bf1a0 is 16 bytes before a block of size 65,536 alloc'd
==85029==    at 0x1000E7545: malloc (vg_replace_malloc.c:302)
==85029==    by 0x100B7B500: __smakebuf (in /usr/lib/system/libsystem_c.dylib)
==85029==    by 0x100B7EC75: __srefill0 (in /usr/lib/system/libsystem_c.dylib)
==85029==    by 0x100B7ED65: __srefill (in /usr/lib/system/libsystem_c.dylib)
==85029==    by 0x100B7B136: getdelim (in /usr/lib/system/libsystem_c.dylib)
==85029==    by 0x10000B0BE: ck_getdelim (utils.c:254)
==85029==    by 0x1000090A9: read_file_line (execute.c:388)
==85029==    by 0x100008A12: read_pattern_space (execute.c:718)
==85029==    by 0x1000066DA: process_files (execute.c:1682)
==85029==    by 0x10000A5D9: main (sed.c:378)
==85029== 
...
FAIL testsuite/bug32082.sh (exit status: 1)

An out-of-bounds read. Oh oh. When I reconfigure and recompile with the
environment variable
  gl_cv_func_working_getdelim=no
this test succeeds. Assuming that the GNU sed code is correct (it's not a
particularly complex code), this proves that the out-of-bounds read comes
from the macOS getdelim() function.

This patch adds a workaround.
TODO: Someone should test the same thing on the *BSD systems as well.


2022-10-16  Bruno Haible  <bruno@clisp.org>

        getdelim: Work around buggy implementation on macOS 10.13.
        * doc/posix-functions/getdelim.texi: Mention the macOS bug.
        * m4/getdelim.m4 (gl_FUNC_GETDELIM): Let the "checking for working
        getdelim function" test answer 'no' on macOS.

diff --git a/doc/posix-functions/getdelim.texi 
b/doc/posix-functions/getdelim.texi
index b076658574..7e1851fac3 100644
--- a/doc/posix-functions/getdelim.texi
+++ b/doc/posix-functions/getdelim.texi
@@ -12,6 +12,9 @@ Portability problems fixed by Gnulib:
 This function is missing on some platforms:
 Mac OS X 10.5, FreeBSD 6.0, NetBSD 5.0, OpenBSD 3.8, Minix 3.1.8, AIX 5.1, 
HP-UX 11, IRIX 6.5, Solaris 10, mingw, MSVC 14, Android 4.2.
 @item
+This function makes out-of-bounds reads on some platforms:
+macOS 10.13.
+@item
 This function crashes when passed a pointer to a NULL buffer together with a
 pointer to a non-zero buffer size on some platforms:
 FreeBSD 8.0.
diff --git a/m4/getdelim.m4 b/m4/getdelim.m4
index 0b63b55351..703c1f876f 100644
--- a/m4/getdelim.m4
+++ b/m4/getdelim.m4
@@ -1,4 +1,4 @@
-# getdelim.m4 serial 15
+# getdelim.m4 serial 16
 
 dnl Copyright (C) 2005-2007, 2009-2022 Free Software Foundation, Inc.
 dnl
@@ -11,7 +11,7 @@ AC_PREREQ([2.59])
 AC_DEFUN([gl_FUNC_GETDELIM],
 [
   AC_REQUIRE([gl_STDIO_H_DEFAULTS])
-  AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
+  AC_REQUIRE([AC_CANONICAL_HOST])
 
   dnl Persuade glibc <stdio.h> to declare getdelim().
   AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS])
@@ -24,8 +24,18 @@ AC_DEFUN([gl_FUNC_GETDELIM],
     dnl Found it in some library.  Verify that it works.
     AC_CACHE_CHECK([for working getdelim function],
       [gl_cv_func_working_getdelim],
-      [echo fooNbarN | tr -d '\012' | tr N '\012' > conftest.data
-       AC_RUN_IFELSE([AC_LANG_SOURCE([[
+      [case "$host_os" in
+         darwin*)
+           dnl On macOS 10.13, valgrind detected an out-of-bounds read during
+           dnl the GNU sed test suite:
+           dnl   Invalid read of size 16
+           dnl      at 0x100EE6A05: _platform_memchr$VARIANT$Base (in 
/usr/lib/system/libsystem_platform.dylib)
+           dnl      by 0x100B7B0BD: getdelim (in 
/usr/lib/system/libsystem_c.dylib)
+           dnl      by 0x10000B0BE: ck_getdelim (utils.c:254)
+           gl_cv_func_working_getdelim=no ;;
+         *)
+           echo fooNbarN | tr -d '\012' | tr N '\012' > conftest.data
+           AC_RUN_IFELSE([AC_LANG_SOURCE([[
 #    include <stdio.h>
 #    include <stdlib.h>
 #    include <string.h>
@@ -57,26 +67,28 @@ AC_DEFUN([gl_FUNC_GETDELIM],
       return 0;
     }
     ]])],
-         [gl_cv_func_working_getdelim=yes],
-         [gl_cv_func_working_getdelim=no],
-         [dnl We're cross compiling.
-          dnl Guess it works on glibc2 systems and musl systems.
-          AC_EGREP_CPP([Lucky GNU user],
-            [
+             [gl_cv_func_working_getdelim=yes],
+             [gl_cv_func_working_getdelim=no],
+             [dnl We're cross compiling.
+              dnl Guess it works on glibc2 systems and musl systems.
+              AC_EGREP_CPP([Lucky GNU user],
+                [
 #include <features.h>
 #ifdef __GNU_LIBRARY__
  #if (__GLIBC__ >= 2) && !defined __UCLIBC__
   Lucky GNU user
  #endif
 #endif
-            ],
-            [gl_cv_func_working_getdelim="guessing yes"],
-            [case "$host_os" in
-               *-musl*) gl_cv_func_working_getdelim="guessing yes" ;;
-               *)       gl_cv_func_working_getdelim="$gl_cross_guess_normal" ;;
-             esac
-            ])
-         ])
+                ],
+                [gl_cv_func_working_getdelim="guessing yes"],
+                [case "$host_os" in
+                   *-musl*) gl_cv_func_working_getdelim="guessing yes" ;;
+                   *)       
gl_cv_func_working_getdelim="$gl_cross_guess_normal" ;;
+                 esac
+                ])
+             ])
+           ;;
+       esac
       ])
     case "$gl_cv_func_working_getdelim" in
       *yes) ;;






reply via email to

[Prev in Thread] Current Thread [Next in Thread]