[Msan] Add ptsname, ptsname_r interceptors
authorVitaly Buka <vitalybuka@google.com>
Wed, 30 Sep 2020 10:02:41 +0000 (03:02 -0700)
committerVitaly Buka <vitalybuka@google.com>
Wed, 30 Sep 2020 22:00:52 +0000 (15:00 -0700)
Reviewed By: eugenis, MaskRay

Differential Revision: https://reviews.llvm.org/D88547

compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc
compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h
compiler-rt/test/sanitizer_common/TestCases/Linux/ptsname.c [new file with mode: 0644]

index 8003534..4ea35ae 100644 (file)
@@ -4867,6 +4867,34 @@ INTERCEPTOR(char *, tmpnam_r, char *s) {
 #define INIT_TMPNAM_R
 #endif
 
+#if SANITIZER_INTERCEPT_PTSNAME
+INTERCEPTOR(char *, ptsname, int fd) {
+  void *ctx;
+  COMMON_INTERCEPTOR_ENTER(ctx, ptsname, fd);
+  char *res = REAL(ptsname)(fd);
+  if (res != nullptr)
+    COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, REAL(strlen)(res) + 1);
+  return res;
+}
+#define INIT_PTSNAME COMMON_INTERCEPT_FUNCTION(ptsname);
+#else
+#define INIT_PTSNAME
+#endif
+
+#if SANITIZER_INTERCEPT_PTSNAME_R
+INTERCEPTOR(int, ptsname_r, int fd, char *name, SIZE_T namesize) {
+  void *ctx;
+  COMMON_INTERCEPTOR_ENTER(ctx, ptsname_r, fd, name, namesize);
+  int res = REAL(ptsname_r)(fd, name, namesize);
+  if (res == 0)
+    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, name, REAL(strlen)(name) + 1);
+  return res;
+}
+#define INIT_PTSNAME_R COMMON_INTERCEPT_FUNCTION(ptsname_r);
+#else
+#define INIT_PTSNAME_R
+#endif
+
 #if SANITIZER_INTERCEPT_TTYNAME
 INTERCEPTOR(char *, ttyname, int fd) {
   void *ctx;
@@ -10166,6 +10194,8 @@ static void InitializeCommonInterceptors() {
   INIT_PTHREAD_BARRIERATTR_GETPSHARED;
   INIT_TMPNAM;
   INIT_TMPNAM_R;
+  INIT_PTSNAME;
+  INIT_PTSNAME_R;
   INIT_TTYNAME;
   INIT_TTYNAME_R;
   INIT_TEMPNAM;
index c28ac55..c6138e7 100644 (file)
 #define SANITIZER_INTERCEPT_THR_EXIT SI_FREEBSD
 #define SANITIZER_INTERCEPT_TMPNAM SI_POSIX
 #define SANITIZER_INTERCEPT_TMPNAM_R SI_LINUX_NOT_ANDROID || SI_SOLARIS
+#define SANITIZER_INTERCEPT_PTSNAME SI_LINUX
+#define SANITIZER_INTERCEPT_PTSNAME_R SI_LINUX
 #define SANITIZER_INTERCEPT_TTYNAME SI_POSIX
 #define SANITIZER_INTERCEPT_TTYNAME_R SI_POSIX
 #define SANITIZER_INTERCEPT_TEMPNAM SI_POSIX
diff --git a/compiler-rt/test/sanitizer_common/TestCases/Linux/ptsname.c b/compiler-rt/test/sanitizer_common/TestCases/Linux/ptsname.c
new file mode 100644 (file)
index 0000000..8fa1d37
--- /dev/null
@@ -0,0 +1,27 @@
+// RUN: %clang %s -o %t && %run %t
+
+#define _GNU_SOURCE
+#define _XOPEN_SOURCE 600
+
+#include <assert.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+int main() {
+  int pt = posix_openpt(O_NOCTTY);
+  if (pt == -1)
+    return 0;
+  char *s = ptsname(pt);
+  assert(s);
+  assert(strstr(s, "/dev"));
+
+  char buff[1000] = {};
+  int r = ptsname_r(pt, buff, sizeof(buff));
+  assert(!r);
+  assert(strstr(buff, "/dev"));
+
+  close(pt);
+  return 0;
+}