replace: Add memset_s() if not available
authorAndreas Schneider <asn@samba.org>
Wed, 10 Oct 2018 14:05:46 +0000 (16:05 +0200)
committerAndreas Schneider <asn@cryptomilk.org>
Tue, 16 Oct 2018 06:42:18 +0000 (08:42 +0200)
See https://en.cppreference.com/w/c/string/byte/memset

Signed-off-by: Andreas Schneider <asn@samba.org>
Reviewed-by: Ralph Boehme <slow@samba.org>
lib/replace/replace.c
lib/replace/replace.h
lib/replace/wscript

index dc81e9cd5aba524d0925201f0496eff82cf080bc..113137c29928c840c7523ffda4d56ca743a97524 100644 (file)
@@ -947,3 +947,34 @@ void rep_setproctitle_init(int argc, char *argv[], char *envp[])
 {
 }
 #endif
+
+#ifndef HAVE_MEMSET_S
+# ifndef RSIZE_MAX
+#  define RSIZE_MAX (SIZE_MAX >> 1)
+# endif
+
+int rep_memset_s(void *dest, size_t destsz, int ch, size_t count)
+{
+       if (dest == NULL) {
+               return EINVAL;
+       }
+
+       if (destsz > RSIZE_MAX ||
+           count > RSIZE_MAX ||
+           count > destsz) {
+               return ERANGE;
+       }
+
+#if defined(HAVE_MEMSET_EXPLICIT)
+       memset_explicit(dest, destsz, ch, count);
+#else /* HAVE_MEMSET_EXPLICIT */
+       memset(dest, ch, count);
+# if defined(HAVE_GCC_VOLATILE_MEMORY_PROTECTION)
+       /* See http://llvm.org/bugs/show_bug.cgi?id=15495 */
+       __asm__ volatile("" : : "g"(dest) : "memory");
+# endif /* HAVE_GCC_VOLATILE_MEMORY_PROTECTION */
+#endif /* HAVE_MEMSET_EXPLICIT */
+
+       return 0;
+}
+#endif /* HAVE_MEMSET_S */
index 626d30530290aa3446ddeb31523264040d82db7e..de4e20c445417c9bb50ba63ddcb4c450bd8bfd18 100644 (file)
@@ -36,6 +36,9 @@
 #include <standards.h>
 #endif
 
+/* Needs to be defined before std*.h and string*.h are included */
+#define __STDC_WANT_LIB_EXT1__ 1
+
 #include <stdio.h>
 #include <stdlib.h>
 #include <stdarg.h>
@@ -925,6 +928,11 @@ void rep_setproctitle(const char *fmt, ...) PRINTF_ATTRIBUTE(1, 2);
 void rep_setproctitle_init(int argc, char *argv[], char *envp[]);
 #endif
 
+#ifndef HAVE_MEMSET_S
+#define memset_s rep_memset_s
+int rep_memset_s(void *dest, size_t destsz, int ch, size_t count);
+#endif
+
 #ifndef FALL_THROUGH
 # ifdef HAVE_FALLTHROUGH_ATTRIBUTE
 #  define FALL_THROUGH __attribute__ ((fallthrough))
index 8e2873424beae2889cad8695ee7d477add378ae3..8adfffe9584e4808672d04ad38542fb717788edb 100644 (file)
@@ -195,6 +195,23 @@ def configure(conf):
                         'socket nsl', checklibc=True,
                         headers='sys/socket.h netinet/in.h arpa/inet.h netdb.h')
 
+    conf.CHECK_FUNCS('memset_s memset_explicit')
+
+    conf.CHECK_CODE('''
+                    #include <string.h>
+
+                    int main(void)
+                    {
+                        char buf[] = "This is some content";
+                        memset(buf, '\0', sizeof(buf)); __asm__ volatile("" : : "g"(&buf) : "memory");
+                        return 0;
+                    }
+                    ''',
+                    define='HAVE_GCC_VOLATILE_MEMORY_PROTECTION',
+                    addmain=False,
+                    msg='Checking for volatile memory protection',
+                    local_include=False)
+
     # Some old Linux systems have broken header files and
     # miss the IPV6_V6ONLY define in netinet/in.h,
     # but have it in linux/in6.h.