diff options
author | Andreas Schneider <asn@samba.org> | 2018-10-10 16:05:46 +0200 |
---|---|---|
committer | Andreas Schneider <asn@cryptomilk.org> | 2018-10-16 08:42:18 +0200 |
commit | 84615c19826895ab57e40ab2b2cdfdc625376097 (patch) | |
tree | 1af8336bfe7b0e1d7b5457350562081d6080dae4 /lib/replace | |
parent | 2fc855e7d2458249ca6fc8ffdf1d7633ab84cc55 (diff) | |
download | samba-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.c | 31 | ||||
-rw-r--r-- | lib/replace/replace.h | 8 | ||||
-rw-r--r-- | lib/replace/wscript | 17 |
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. |