[compiler-rt] 339f1b4 - sanitizers: Add interceptors for getproto{ent,byname,bynumber}_r

Gui Andrade via llvm-commits llvm-commits at lists.llvm.org
Wed Jul 8 14:44:50 PDT 2020


Author: Gui Andrade
Date: 2020-07-08T21:41:18Z
New Revision: 339f1b49037bd7fbd1454c872bcfd1bb6c380f5d

URL: https://github.com/llvm/llvm-project/commit/339f1b49037bd7fbd1454c872bcfd1bb6c380f5d
DIFF: https://github.com/llvm/llvm-project/commit/339f1b49037bd7fbd1454c872bcfd1bb6c380f5d.diff

LOG: sanitizers: Add interceptors for getproto{ent,byname,bynumber}_r

This also allows intercepting these getprotoent functions on Linux as
well, since Linux exposes them.

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

Added: 
    compiler-rt/test/sanitizer_common/TestCases/Linux/protoent.cpp

Modified: 
    compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc
    compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h
    compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_netbsd.h
    compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.h

Removed: 
    


################################################################################
diff  --git a/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc b/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc
index 053e559a9f90..ea9c71ba8803 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc
@@ -7299,23 +7299,26 @@ INTERCEPTOR(int, setttyentpath, char *path) {
 #endif
 
 #if SANITIZER_INTERCEPT_PROTOENT
-INTERCEPTOR(struct __sanitizer_protoent *, getprotoent) {
-  void *ctx;
-  COMMON_INTERCEPTOR_ENTER(ctx, getprotoent);
-  struct __sanitizer_protoent *p = REAL(getprotoent)();
-  if (p) {
-    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, sizeof(*p));
+static void write_protoent(void *ctx, struct __sanitizer_protoent *p) {
+  COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, sizeof(*p));
 
-    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->p_name, REAL(strlen)(p->p_name) + 1);
+  COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->p_name, REAL(strlen)(p->p_name) + 1);
 
-    SIZE_T pp_size = 1; // One handles the trailing \0
+  SIZE_T pp_size = 1; // One handles the trailing \0
 
-    for (char **pp = p->p_aliases; *pp; ++pp, ++pp_size)
-       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *pp, REAL(strlen)(*pp) + 1);
+  for (char **pp = p->p_aliases; *pp; ++pp, ++pp_size)
+      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *pp, REAL(strlen)(*pp) + 1);
 
-    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->p_aliases,
-                                   pp_size * sizeof(char **));
-  }
+  COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->p_aliases,
+                                  pp_size * sizeof(char **));
+}
+
+INTERCEPTOR(struct __sanitizer_protoent *, getprotoent) {
+  void *ctx;
+  COMMON_INTERCEPTOR_ENTER(ctx, getprotoent);
+  struct __sanitizer_protoent *p = REAL(getprotoent)();
+  if (p)
+    write_protoent(ctx, p);
   return p;
 }
 
@@ -7325,19 +7328,8 @@ INTERCEPTOR(struct __sanitizer_protoent *, getprotobyname, const char *name) {
   if (name)
     COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1);
   struct __sanitizer_protoent *p = REAL(getprotobyname)(name);
-  if (p) {
-    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, sizeof(*p));
-
-    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->p_name, REAL(strlen)(p->p_name) + 1);
-
-    SIZE_T pp_size = 1; // One handles the trailing \0
-
-    for (char **pp = p->p_aliases; *pp; ++pp, ++pp_size)
-       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *pp, REAL(strlen)(*pp) + 1);
-
-    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->p_aliases,
-                                   pp_size * sizeof(char **));
-  }
+  if (p)
+    write_protoent(ctx, p);
   return p;
 }
 
@@ -7345,19 +7337,8 @@ INTERCEPTOR(struct __sanitizer_protoent *, getprotobynumber, int proto) {
   void *ctx;
   COMMON_INTERCEPTOR_ENTER(ctx, getprotobynumber, proto);
   struct __sanitizer_protoent *p = REAL(getprotobynumber)(proto);
-  if (p) {
-    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, sizeof(*p));
-
-    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->p_name, REAL(strlen)(p->p_name) + 1);
-
-    SIZE_T pp_size = 1; // One handles the trailing \0
-
-    for (char **pp = p->p_aliases; *pp; ++pp, ++pp_size)
-       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *pp, REAL(strlen)(*pp) + 1);
-
-    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->p_aliases,
-                                   pp_size * sizeof(char **));
-  }
+  if (p)
+    write_protoent(ctx, p);
   return p;
 }
 #define INIT_PROTOENT \
@@ -7368,6 +7349,58 @@ INTERCEPTOR(struct __sanitizer_protoent *, getprotobynumber, int proto) {
 #define INIT_PROTOENT
 #endif
 
+#if SANITIZER_INTERCEPT_PROTOENT_R
+INTERCEPTOR(int, getprotoent_r, struct __sanitizer_protoent *result_buf,
+            char *buf, SIZE_T buflen, struct __sanitizer_protoent **result) {
+  void *ctx;
+  COMMON_INTERCEPTOR_ENTER(ctx, getprotoent_r, result_buf, buf, buflen,
+                           result);
+  int res = REAL(getprotoent_r)(result_buf, buf, buflen, result);
+
+  COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof *result);
+  if (!res && *result)
+    write_protoent(ctx, *result);
+  return res;
+}
+
+INTERCEPTOR(int, getprotobyname_r, const char *name,
+            struct __sanitizer_protoent *result_buf, char *buf, SIZE_T buflen,
+            struct __sanitizer_protoent **result) {
+  void *ctx;
+  COMMON_INTERCEPTOR_ENTER(ctx, getprotobyname_r, name, result_buf, buf,
+                           buflen, result);
+  if (name)
+    COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1);
+  int res = REAL(getprotobyname_r)(name, result_buf, buf, buflen, result);
+
+  COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof *result);
+  if (!res && *result)
+    write_protoent(ctx, *result);
+  return res;
+}
+
+INTERCEPTOR(int, getprotobynumber_r, int num,
+            struct __sanitizer_protoent *result_buf, char *buf,
+            SIZE_T buflen, struct __sanitizer_protoent **result) {
+  void *ctx;
+  COMMON_INTERCEPTOR_ENTER(ctx, getprotobynumber_r, num, result_buf, buf,
+                           buflen, result);
+  int res = REAL(getprotobynumber_r)(num, result_buf, buf, buflen, result);
+
+  COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof *result);
+  if (!res && *result)
+    write_protoent(ctx, *result);
+  return res;
+}
+
+#define INIT_PROTOENT_R \
+  COMMON_INTERCEPT_FUNCTION(getprotoent_r); \
+  COMMON_INTERCEPT_FUNCTION(getprotobyname_r); \
+  COMMON_INTERCEPT_FUNCTION(getprotobynumber_r);
+#else
+#define INIT_PROTOENT_R
+#endif
+
 #if SANITIZER_INTERCEPT_NETENT
 INTERCEPTOR(struct __sanitizer_netent *, getnetent) {
   void *ctx;
@@ -10071,6 +10104,7 @@ static void InitializeCommonInterceptors() {
   INIT_STRMODE;
   INIT_TTYENT;
   INIT_PROTOENT;
+  INIT_PROTOENT_R;
   INIT_NETENT;
   INIT_GETMNTINFO;
   INIT_MI_VECTOR_HASH;

diff  --git a/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h b/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h
index a5fcbadb2597..2d48e9d0ae1a 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h
@@ -545,7 +545,8 @@
 #define SANITIZER_INTERCEPT_FGETLN (SI_NETBSD || SI_FREEBSD)
 #define SANITIZER_INTERCEPT_STRMODE (SI_NETBSD || SI_FREEBSD)
 #define SANITIZER_INTERCEPT_TTYENT SI_NETBSD
-#define SANITIZER_INTERCEPT_PROTOENT SI_NETBSD
+#define SANITIZER_INTERCEPT_PROTOENT (SI_NETBSD || SI_LINUX)
+#define SANITIZER_INTERCEPT_PROTOENT_R (SI_LINUX_NOT_ANDROID)
 #define SANITIZER_INTERCEPT_NETENT SI_NETBSD
 #define SANITIZER_INTERCEPT_SETVBUF (SI_NETBSD || SI_FREEBSD || \
   SI_LINUX || SI_MAC)

diff  --git a/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_netbsd.h b/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_netbsd.h
index d80280d9bf8c..ae54a8cf105e 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_netbsd.h
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_netbsd.h
@@ -129,12 +129,6 @@ struct __sanitizer_shmid_ds {
   void *_shm_internal;
 };
 
-struct __sanitizer_protoent {
-  char *p_name;
-  char **p_aliases;
-  int p_proto;
-};
-
 struct __sanitizer_netent {
   char *n_name;
   char **n_aliases;

diff  --git a/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.h b/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.h
index f6c8a1450a93..658b0abaece8 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.h
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.h
@@ -704,6 +704,12 @@ struct __sanitizer_dl_phdr_info {
 extern unsigned struct_ElfW_Phdr_sz;
 #endif
 
+struct __sanitizer_protoent {
+  char *p_name;
+  char **p_aliases;
+  int p_proto;
+};
+
 struct __sanitizer_addrinfo {
   int ai_flags;
   int ai_family;

diff  --git a/compiler-rt/test/sanitizer_common/TestCases/Linux/protoent.cpp b/compiler-rt/test/sanitizer_common/TestCases/Linux/protoent.cpp
new file mode 100644
index 000000000000..1b4e90a407ac
--- /dev/null
+++ b/compiler-rt/test/sanitizer_common/TestCases/Linux/protoent.cpp
@@ -0,0 +1,62 @@
+// RUN: %clangxx -std=c++11 -O0 -g %s -o %t && %run %t 2>&1 | FileCheck %s
+
+#include <assert.h>
+#include <errno.h>
+#include <netdb.h>
+#include <stdio.h>
+
+void print_protoent(protoent *curr_entry) {
+  fprintf(stderr, "%s (%d)\n", curr_entry->p_name, curr_entry->p_proto);
+
+  char **aliases = curr_entry->p_aliases;
+  while (char *alias = *aliases++) {
+    fprintf(stderr, "  alias %s\n", alias);
+  }
+}
+
+void print_all_protoent() {
+  protoent entry;
+  char buf[1024];
+  protoent *curr_entry;
+
+  while (getprotoent_r(&entry, buf, sizeof(buf), &curr_entry) != ENOENT && curr_entry) {
+    print_protoent(curr_entry);
+  }
+}
+
+void print_protoent_by_name(const char *name) {
+  protoent entry;
+  char buf[1024];
+  protoent *curr_entry;
+
+  int res = getprotobyname_r(name, &entry, buf, sizeof(buf), &curr_entry);
+  assert(!res && curr_entry);
+  print_protoent(curr_entry);
+}
+
+void print_protoent_by_num(int num) {
+  protoent entry;
+  char buf[1024];
+  protoent *curr_entry;
+
+  int res = getprotobynumber_r(num, &entry, buf, sizeof(buf), &curr_entry);
+  assert(!res && curr_entry);
+  print_protoent(curr_entry);
+}
+
+int main() {
+  // CHECK: ip (0)
+  // CHECK-NEXT: alias IP
+  // CHECK: ipv6 (41)
+  // CHECK-NEXT: alias IPv6
+  print_all_protoent();
+
+  // CHECK: rdp (27)
+  // CHECK-NEXT: alias RDP
+  print_protoent_by_name("rdp");
+
+  // CHECK: udp (17)
+  // CHECK-NEXT: alias UDP
+  print_protoent_by_num(17);
+  return 0;
+}


        


More information about the llvm-commits mailing list