summaryrefslogtreecommitdiff
path: root/lib/replace
diff options
context:
space:
mode:
authorAndreas Schneider <asn@samba.org>2018-10-10 16:05:46 +0200
committerAndreas Schneider <asn@cryptomilk.org>2018-10-16 08:42:18 +0200
commit84615c19826895ab57e40ab2b2cdfdc625376097 (patch)
tree1af8336bfe7b0e1d7b5457350562081d6080dae4 /lib/replace
parent2fc855e7d2458249ca6fc8ffdf1d7633ab84cc55 (diff)
downloadsamba-84615c19826895ab57e40ab2b2cdfdc625376097.tar.gz
replace: Add memset_s() if not available
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>
Diffstat (limited to 'lib/replace')
-rw-r--r--lib/replace/replace.c31
-rw-r--r--lib/replace/replace.h8
-rw-r--r--lib/replace/wscript17
3 files changed, 56 insertions, 0 deletions
diff --git a/lib/replace/replace.c b/lib/replace/replace.c
index dc81e9cd5ab..113137c2992 100644
--- a/lib/replace/replace.c
+++ b/lib/replace/replace.c
@@ -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 */
diff --git a/lib/replace/replace.h b/lib/replace/replace.h
index 626d3053029..de4e20c4454 100644
--- a/lib/replace/replace.h
+++ b/lib/replace/replace.h
@@ -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))
diff --git a/lib/replace/wscript b/lib/replace/wscript
index 8e2873424be..8adfffe9584 100644
--- a/lib/replace/wscript
+++ b/lib/replace/wscript
@@ -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.