From a5c9e6790d373c6b355087d544a42ad63466211c Mon Sep 17 00:00:00 2001 From: Evgeniy Stepanov Date: Mon, 14 Jul 2014 13:07:51 +0000 Subject: [sanitizer] Intercept getpass. git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@212937 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../sanitizer_common_interceptors.inc | 17 +++++++++++ .../sanitizer_platform_interceptors.h | 1 + test/sanitizer_common/TestCases/Linux/getpass.cc | 33 ++++++++++++++++++++++ 3 files changed, 51 insertions(+) create mode 100644 test/sanitizer_common/TestCases/Linux/getpass.cc 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 +#include +#include +#include +#include + +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 -- cgit v1.2.3