summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Micay <danielmicay@gmail.com>2015-02-05 21:53:16 -0500
committeralk3pInjection <webmaster@raspii.tech>2021-09-27 21:17:05 +0800
commit2780434e17939a9bbda1212f44a0ab655c539f6a (patch)
treec7b9cd415914274a207c8b63d68d6872f1b7ff52
parent3a003876ad043c5280e0fbb334e8d17c3d941bfc (diff)
[GrapheneOS] add a real explicit_bzero implementation
Clang, GCC and other compilers special-case standard C functions like memset. Calls to memset will be optimized out. OpenBSD provides explicit_bzero to work around this but Android simply defines it as memset so nothing prevents it from being optimized away. This implementation uses a memory read constraint via empty inline assembly rather than something that may be broken via link-time optimization in the future. Change-Id: I6005d65a2afd4bd54aacfdfa633d215a58e9907a
-rw-r--r--libc/Android.bp1
-rw-r--r--libc/bionic/explicit_bzero.cpp7
-rw-r--r--libc/include/string.h1
-rw-r--r--libc/libc.map.txt1
-rw-r--r--libc/upstream-openbsd/android/include/openbsd-compat.h2
5 files changed, 10 insertions, 2 deletions
diff --git a/libc/Android.bp b/libc/Android.bp
index ce714054a..49108bf35 100644
--- a/libc/Android.bp
+++ b/libc/Android.bp
@@ -1047,6 +1047,7 @@ cc_library_static {
"bionic/error.cpp",
"bionic/eventfd.cpp",
"bionic/exec.cpp",
+ "bionic/explicit_bzero.cpp",
"bionic/faccessat.cpp",
"bionic/fchmod.cpp",
"bionic/fchmodat.cpp",
diff --git a/libc/bionic/explicit_bzero.cpp b/libc/bionic/explicit_bzero.cpp
new file mode 100644
index 000000000..b06daa138
--- /dev/null
+++ b/libc/bionic/explicit_bzero.cpp
@@ -0,0 +1,7 @@
+#include <string.h>
+
+void* explicit_bzero(void* s, size_t n) {
+ void *ptr = memset(s, 0, n);
+ __asm__ __volatile__("" : : "r"(ptr) : "memory");
+ return ptr;
+}
diff --git a/libc/include/string.h b/libc/include/string.h
index 0cc5611aa..befffd082 100644
--- a/libc/include/string.h
+++ b/libc/include/string.h
@@ -56,6 +56,7 @@ void* mempcpy(void* __dst, const void* __src, size_t __n) __INTRODUCED_IN(23);
#endif
void* memmove(void* __dst, const void* __src, size_t __n);
void* memset(void* __dst, int __ch, size_t __n);
+void* explicit_bzero(void *s, size_t n);
void* memmem(const void* __haystack, size_t __haystack_size, const void* __needle, size_t __needle_size) __attribute_pure__;
char* strchr(const char* __s, int __ch) __attribute_pure__;
diff --git a/libc/libc.map.txt b/libc/libc.map.txt
index 4bfb8a232..36803984e 100644
--- a/libc/libc.map.txt
+++ b/libc/libc.map.txt
@@ -332,6 +332,7 @@ LIBC {
execvp;
execvpe; # introduced=21
exit;
+ explicit_bzero; # introduced=30
faccessat;
fallocate; # introduced=21
fallocate64; # introduced=21
diff --git a/libc/upstream-openbsd/android/include/openbsd-compat.h b/libc/upstream-openbsd/android/include/openbsd-compat.h
index 878f71cec..79a260425 100644
--- a/libc/upstream-openbsd/android/include/openbsd-compat.h
+++ b/libc/upstream-openbsd/android/include/openbsd-compat.h
@@ -53,8 +53,6 @@ extern const char* __progname;
/* OpenBSD has this, but we can't really implement it correctly on Linux. */
#define issetugid() 0
-#define explicit_bzero(p, s) memset(p, 0, s)
-
/* OpenBSD has these in <sys/param.h>, but "ALIGN" isn't something we want to reserve. */
#define ALIGNBYTES (sizeof(uintptr_t) - 1)
#define ALIGN(p) (((uintptr_t)(p) + ALIGNBYTES) &~ ALIGNBYTES)