diff options
author | Kamil Rytarowski <n54@gmx.com> | 2018-02-27 02:33:30 +0000 |
---|---|---|
committer | Kamil Rytarowski <n54@gmx.com> | 2018-02-27 02:33:30 +0000 |
commit | a3d3defff92476dc862affc7ab4ca8acd0408852 (patch) | |
tree | 70d01b10d63c375e6db00864d2cadbb05e1a0bff | |
parent | 2332b74dc3067b27a5577ff203789c41d7ca09d8 (diff) |
Add new interceptors: getnetent(3) family
Summary:
getnetent, getnetbyaddr, getnetbyname - get network entry
Reuse them on NetBSD.
Sponsored by <The NetBSD Foundation>
Reviewers: joerg, vitalybuka
Reviewed By: vitalybuka
Subscribers: llvm-commits, kubamracek, #sanitizers
Tags: #sanitizers
Differential Revision: https://reviews.llvm.org/D43543
git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@326163 91177308-0d34-0410-b5e6-96231b3b80d8
4 files changed, 163 insertions, 0 deletions
diff --git a/lib/sanitizer_common/sanitizer_common_interceptors.inc b/lib/sanitizer_common/sanitizer_common_interceptors.inc index 8cd329f1a..7f6bc3412 100644 --- a/lib/sanitizer_common/sanitizer_common_interceptors.inc +++ b/lib/sanitizer_common/sanitizer_common_interceptors.inc @@ -6955,6 +6955,76 @@ INTERCEPTOR(struct __sanitizer_protoent *, getprotobynumber, int proto) { #define INIT_PROTOENT #endif +#if SANITIZER_INTERCEPT_NETENT +INTERCEPTOR(struct __sanitizer_netent *, getnetent) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, getnetent); + struct __sanitizer_netent *n = REAL(getnetent)(); + if (n) { + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, n, sizeof(*n)); + + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, n->n_name, REAL(strlen)(n->n_name) + 1); + + SIZE_T nn_size = 1; // One handles the trailing \0 + + for (char **nn = n->n_aliases; *nn; ++nn, ++nn_size) + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *nn, REAL(strlen)(*nn) + 1); + + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, n->n_aliases, + nn_size * sizeof(char **)); + } + return n; +} + +INTERCEPTOR(struct __sanitizer_netent *, getnetbyname, const char *name) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, getnetbyname, name); + if (name) + COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1); + struct __sanitizer_netent *n = REAL(getnetbyname)(name); + if (n) { + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, n, sizeof(*n)); + + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, n->n_name, REAL(strlen)(n->n_name) + 1); + + SIZE_T nn_size = 1; // One handles the trailing \0 + + for (char **nn = n->n_aliases; *nn; ++nn, ++nn_size) + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *nn, REAL(strlen)(*nn) + 1); + + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, n->n_aliases, + nn_size * sizeof(char **)); + } + return n; +} + +INTERCEPTOR(struct __sanitizer_netent *, getnetbyaddr, u32 net, int type) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, getnetbyaddr, net, type); + struct __sanitizer_netent *n = REAL(getnetbyaddr)(net, type); + if (n) { + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, n, sizeof(*n)); + + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, n->n_name, REAL(strlen)(n->n_name) + 1); + + SIZE_T nn_size = 1; // One handles the trailing \0 + + for (char **nn = n->n_aliases; *nn; ++nn, ++nn_size) + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *nn, REAL(strlen)(*nn) + 1); + + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, n->n_aliases, + nn_size * sizeof(char **)); + } + return n; +} +#define INIT_NETENT \ + COMMON_INTERCEPT_FUNCTION(getnetent); \ + COMMON_INTERCEPT_FUNCTION(getnetbyname); \ + COMMON_INTERCEPT_FUNCTION(getnetbyaddr) +#else +#define INIT_NETENT +#endif + static void InitializeCommonInterceptors() { static u64 metadata_mem[sizeof(MetadataHashMap) / sizeof(u64) + 1]; interceptor_metadata_map = new((void *)&metadata_mem) MetadataHashMap(); @@ -7187,6 +7257,7 @@ static void InitializeCommonInterceptors() { INIT_STRMODE; INIT_TTYENT; INIT_PROTOENT; + INIT_NETENT; #if SANITIZER_NETBSD COMMON_INTERCEPT_FUNCTION(__libc_mutex_lock); diff --git a/lib/sanitizer_common/sanitizer_platform_interceptors.h b/lib/sanitizer_common/sanitizer_platform_interceptors.h index 856109c08..e44eb568e 100644 --- a/lib/sanitizer_common/sanitizer_platform_interceptors.h +++ b/lib/sanitizer_common/sanitizer_platform_interceptors.h @@ -463,5 +463,6 @@ #define SANITIZER_INTERCEPT_STRMODE SI_NETBSD #define SANITIZER_INTERCEPT_TTYENT SI_NETBSD #define SANITIZER_INTERCEPT_PROTOENT SI_NETBSD +#define SANITIZER_INTERCEPT_NETENT SI_NETBSD #endif // #ifndef SANITIZER_PLATFORM_INTERCEPTORS_H diff --git a/lib/sanitizer_common/sanitizer_platform_limits_netbsd.h b/lib/sanitizer_common/sanitizer_platform_limits_netbsd.h index 0ab37f53c..97614cf63 100644 --- a/lib/sanitizer_common/sanitizer_platform_limits_netbsd.h +++ b/lib/sanitizer_common/sanitizer_platform_limits_netbsd.h @@ -119,6 +119,13 @@ struct __sanitizer_protoent { int p_proto; }; +struct __sanitizer_netent { + char *n_name; + char **n_aliases; + int n_addrtype; + u32 n_net; +}; + extern unsigned struct_msqid_ds_sz; extern unsigned struct_mq_attr_sz; extern unsigned struct_timex_sz; diff --git a/test/sanitizer_common/TestCases/NetBSD/netent.cc b/test/sanitizer_common/TestCases/NetBSD/netent.cc new file mode 100644 index 000000000..b574a9310 --- /dev/null +++ b/test/sanitizer_common/TestCases/NetBSD/netent.cc @@ -0,0 +1,84 @@ +// RUN: %clangxx -O0 -g %s -o %t && %run %t 2>&1 | FileCheck %s + +#include <inttypes.h> +#include <netdb.h> +#include <stdint.h> +#include <stdio.h> +#include <stdlib.h> + +#define STRING_OR_NULL(x) ((x) ? (x) : "null") + +void test1() { + struct netent *ntp = getnetent(); + + printf("%s ", ntp->n_name); + + for (char **cp = ntp->n_aliases; *cp != NULL; cp++) + printf("%s ", STRING_OR_NULL(*cp)); + + printf("%d ", ntp->n_addrtype); + printf("%" PRIu32 "\n", ntp->n_net); + + endnetent(); +} + +void test2() { + struct netent *ntp = getnetbyname("loopback"); + + printf("%s ", ntp->n_name); + + for (char **cp = ntp->n_aliases; *cp != NULL; cp++) + printf("%s ", STRING_OR_NULL(*cp)); + + printf("%d ", ntp->n_addrtype); + printf("%" PRIu32 "\n", ntp->n_net); + + endnetent(); +} + +void test3() { + struct netent *ntp = getnetbyaddr(127, 2); + + printf("%s ", ntp->n_name); + + for (char **cp = ntp->n_aliases; *cp != NULL; cp++) + printf("%s ", STRING_OR_NULL(*cp)); + + printf("%d ", ntp->n_addrtype); + printf("%" PRIu32 "\n", ntp->n_net); + + endnetent(); +} + +void test4() { + setnetent(1); + + struct netent *ntp = getnetent(); + + printf("%s ", ntp->n_name); + + for (char **cp = ntp->n_aliases; *cp != NULL; cp++) + printf("%s ", STRING_OR_NULL(*cp)); + + printf("%d ", ntp->n_addrtype); + printf("%" PRIu32 "\n", ntp->n_net); + + endnetent(); +} + +int main(void) { + printf("netent\n"); + + test1(); + test2(); + test3(); + test4(); + + // CHECK: netent + // CHECK: loopback 2 127 + // CHECK: loopback 2 127 + // CHECK: loopback 2 127 + // CHECK: loopback 2 127 + + return 0; +} |