Skip to content

Commit 5cd7b8b

Browse files
committed
[compiler-rt][sanitizer-common] intercept getaddrinfo_a for Linux.
1 parent 1797fb6 commit 5cd7b8b

File tree

5 files changed

+102
-0
lines changed

5 files changed

+102
-0
lines changed

compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10263,6 +10263,58 @@ INTERCEPTOR(SSIZE_T, freadlink, int fd, char *buf, SIZE_T bufsiz) {
1026310263
# define INIT_FREADLINK
1026410264
#endif
1026510265

10266+
#if SANITIZER_INTERCEPT_GETADDRINFO_A
10267+
INTERCEPTOR(int, getaddrinfo_a, int mode, struct __sanitizer_gaicb *list,
10268+
int num, void *sevp) {
10269+
void *ctx;
10270+
COMMON_INTERCEPTOR_ENTER(ctx, getaddrinfo_a, mode, list, num, sevp);
10271+
if (sevp)
10272+
COMMON_INTERCEPTOR_READ_RANGE(ctx, sevp, struct_sigevent_sz);
10273+
if (list) {
10274+
for (int i = 0; i < num; i++) {
10275+
struct __sanitizer_gaicb *cb = list[i];
10276+
COMMON_INTERCEPTOR_READ_RANGE(ctx, cb, sizeof(__sanitizer_gaicb));
10277+
if (cb->ar_name)
10278+
COMMON_INTERCEPTOR_READ_RANGE(ctx, cb->ar_name,
10279+
internal_strlen(cb->ar_name) + 1);
10280+
if (cb->ar_service)
10281+
COMMON_INTERCEPTOR_READ_RANGE(ctx, cb->ar_service,
10282+
internal_strlen(cb->ar_service) + 1);
10283+
if (cb->ar_request) {
10284+
COMMON_INTERCEPTOR_READ_RANGE(ctx, cb->ar_request,
10285+
sizeof(__sanitizer_addrinfo));
10286+
}
10287+
}
10288+
}
10289+
10290+
int res = REAL(getaddrinfo_a)(mode, list, num, sevp);
10291+
if (res == 0 && list) {
10292+
for (int i = 0; i < num; i++) {
10293+
struct __sanitizer_addrinfo *result = list[i]->ar_result;
10294+
if (result) {
10295+
while (result) {
10296+
COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result,
10297+
sizeof(__sanitizer_addrinfo));
10298+
if (result->ai_addr)
10299+
COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result->ai_addr,
10300+
result->ai_addrlen);
10301+
if (result->ai_canonname)
10302+
COMMON_INTERCEPTOR_WRITE_RANGE(
10303+
ctx, result->ai_canonname,
10304+
internal_strlen(result->ai_canonname) + 1);
10305+
result = result->ai_next;
10306+
}
10307+
}
10308+
}
10309+
}
10310+
10311+
return res;
10312+
}
10313+
# define INIT_GETADDRINFO_A COMMON_INTERCEPT_FUNCTION(getaddrinfo_a)
10314+
#else
10315+
# define INIT_GETADDRINFO_A
10316+
#endif
10317+
1026610318
#include "sanitizer_common_interceptors_netbsd_compat.inc"
1026710319

1026810320
namespace __sanitizer {
@@ -10585,6 +10637,7 @@ static void InitializeCommonInterceptors() {
1058510637
INIT_PREADV2;
1058610638
INIT_PWRITEV2;
1058710639
INIT_FREADLINK;
10640+
INIT_GETADDRINFO_A;
1058810641

1058910642
INIT___PRINTF_CHK;
1059010643
}

compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -640,6 +640,7 @@ SANITIZER_WEAK_IMPORT void *aligned_alloc(__sanitizer::usize __alignment,
640640
# define SI_MAC_OS_DEPLOYMENT_MIN_13_00 0
641641
#endif
642642
#define SANITIZER_INTERCEPT_FREADLINK (SI_MAC && SI_MAC_OS_DEPLOYMENT_MIN_13_00)
643+
#define SANITIZER_GETADDRINFO_A SI_LINUX
643644
// This macro gives a way for downstream users to override the above
644645
// interceptor macros irrespective of the platform they are on. They have
645646
// to do two things:

compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1172,6 +1172,12 @@ CHECK_TYPE_SIZE(__kernel_old_gid_t);
11721172
CHECK_TYPE_SIZE(__kernel_off_t);
11731173
CHECK_TYPE_SIZE(__kernel_loff_t);
11741174
CHECK_TYPE_SIZE(__kernel_fd_set);
1175+
1176+
CHECK_TYPE_SIZE(gaicb);
1177+
CHECK_SIZE_AND_OFFSET(gaicb, ar_name);
1178+
CHECK_SIZE_AND_OFFSET(gaicb, ar_service);
1179+
CHECK_SIZE_AND_OFFSET(gaicb, ar_request);
1180+
CHECK_SIZE_AND_OFFSET(gaicb, ar_result);
11751181
#endif
11761182

11771183
#if !SANITIZER_ANDROID

compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -788,6 +788,16 @@ struct __sanitizer_addrinfo {
788788
struct __sanitizer_addrinfo *ai_next;
789789
};
790790

791+
# if SANITIZER_LINUX
792+
struct __sanitizer_gaicb {
793+
const char *ar_name;
794+
const char *ar_service;
795+
const struct __sanitizer_addrinfo *ar_request;
796+
struct __sanitizer_addrinfo *ar_result;
797+
int __pad[6];
798+
};
799+
# endif
800+
791801
struct __sanitizer_hostent {
792802
char *h_name;
793803
char **h_aliases;
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
// RUN: %clangxx_msan -fsanitize-memory-track-origins -O0 %s -o %t && not %run %t >%t.out 2>&1
2+
// RUN: FileCheck %s < %t.out && FileCheck %s < %t.out
3+
4+
#include <netdb.h>
5+
#include <stdlib.h>
6+
#include <string.h>
7+
#include <sys/socket.h>
8+
#include <sys/types.h>
9+
10+
int main(void) {
11+
const int nm = 4;
12+
struct gaicb *list[nm];
13+
14+
for (auto i = 0; i < nm; i++) {
15+
list[i] = (struct gaicb *)malloc(sizeof(struct gaicb));
16+
if (i % 2)
17+
memset(list[i], 0, sizeof(struct gaicb));
18+
list[i]->ar_name = "name";
19+
}
20+
21+
int res = getaddrinfo_a(GAI_WAIT, list, nm, NULL);
22+
for (auto i = 0; i < nm; i++) {
23+
// CHECK: WARNING: MemorySanitizer: use-of-uninitialized-value
24+
// CHECK: {{#0 .* in main.*getaddrinfo_a.cpp:25}}
25+
for (auto it = list[i]->ar_result; it; it = it->ai_next) {
26+
auto name = it->ai_canonname;
27+
}
28+
29+
free(list[i]);
30+
}
31+
return 0;
32+
}

0 commit comments

Comments
 (0)