aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEvgeniy Stepanov <eugeni.stepanov@gmail.com>2014-07-14 13:07:51 +0000
committerEvgeniy Stepanov <eugeni.stepanov@gmail.com>2014-07-14 13:07:51 +0000
commita5c9e6790d373c6b355087d544a42ad63466211c (patch)
treeedf0395d1854bbdbc7610a169ea8549125c90bb1
parent01ed54b80ea0c0b149ebe16a37f4ebd5480f96d1 (diff)
downloadcompiler-rt-a5c9e6790d373c6b355087d544a42ad63466211c.tar.gz
[sanitizer] Intercept getpass.
git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@212937 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/sanitizer_common/sanitizer_common_interceptors.inc17
-rw-r--r--lib/sanitizer_common/sanitizer_platform_interceptors.h1
-rw-r--r--test/sanitizer_common/TestCases/Linux/getpass.cc33
3 files changed, 51 insertions, 0 deletions
diff --git a/lib/sanitizer_common/sanitizer_common_interceptors.inc b/lib/sanitizer_common/sanitizer_common_interceptors.inc
index 64ddeed3d..339434e31 100644
--- a/lib/sanitizer_common/sanitizer_common_interceptors.inc
+++ b/lib/sanitizer_common/sanitizer_common_interceptors.inc
@@ -4628,6 +4628,22 @@ INTERCEPTOR(int, dlclose, void *handle) {
#define INIT_DLOPEN_DLCLOSE
#endif
+#if SANITIZER_INTERCEPT_GETPASS
+INTERCEPTOR(char *, getpass, const char *prompt) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, getpass, prompt);
+ if (prompt)
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, prompt, REAL(strlen)(prompt)+1);
+ char *res = REAL(getpass)(prompt);
+ if (res) COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, REAL(strlen)(res)+1);
+ return res;
+}
+
+#define INIT_GETPASS COMMON_INTERCEPT_FUNCTION(getpass);
+#else
+#define INIT_GETPASS
+#endif
+
static void InitializeCommonInterceptors() {
static u64 metadata_mem[sizeof(MetadataHashMap) / sizeof(u64) + 1];
interceptor_metadata_map = new((void *)&metadata_mem) MetadataHashMap();
@@ -4786,4 +4802,5 @@ static void InitializeCommonInterceptors() {
INIT_FFLUSH;
INIT_FCLOSE;
INIT_DLOPEN_DLCLOSE;
+ INIT_GETPASS;
}
diff --git a/lib/sanitizer_common/sanitizer_platform_interceptors.h b/lib/sanitizer_common/sanitizer_platform_interceptors.h
index e9d5c35a7..9b8c19cb5 100644
--- a/lib/sanitizer_common/sanitizer_platform_interceptors.h
+++ b/lib/sanitizer_common/sanitizer_platform_interceptors.h
@@ -222,5 +222,6 @@
#define SANITIZER_INTERCEPT_FFLUSH SI_NOT_WINDOWS
#define SANITIZER_INTERCEPT_FCLOSE SI_NOT_WINDOWS
#define SANITIZER_INTERCEPT_DLOPEN_DLCLOSE SI_LINUX_NOT_ANDROID || SI_MAC
+#define SANITIZER_INTERCEPT_GETPASS SI_LINUX_NOT_ANDROID || SI_MAC
#endif // #ifndef SANITIZER_PLATFORM_INTERCEPTORS_H
diff --git a/test/sanitizer_common/TestCases/Linux/getpass.cc b/test/sanitizer_common/TestCases/Linux/getpass.cc
new file mode 100644
index 000000000..717f77502
--- /dev/null
+++ b/test/sanitizer_common/TestCases/Linux/getpass.cc
@@ -0,0 +1,33 @@
+// RUN: %clangxx -O0 -g %s -lutil -o %t && %run %t | FileCheck %s
+#include <assert.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <string.h>
+#include <pty.h>
+
+int
+main (int argc, char** argv)
+{
+ int master;
+ int pid = forkpty(&master, NULL, NULL, NULL);
+
+ if(pid == -1) {
+ fprintf(stderr, "forkpty failed\n");
+ return 1;
+ } else if (pid > 0) {
+ char buf[1024];
+ int res = read(master, buf, sizeof(buf));
+ write(1, buf, res);
+ write(master, "password\n", 9);
+ res = read(master, buf, sizeof(buf));
+ write(1, buf, res);
+ } else {
+ char *s = getpass("prompt");
+ assert(strcmp(s, "password") == 0);
+ write(1, "done\n", 5);
+ }
+ return 0;
+}
+
+// CHECK: prompt
+// CHECK: done