[msan] Fix gethostbyname_r and similar interceptors.

*h_errno is written not on success, but on failure.
In fact, it seems like it can be written even when return value signals
success, so we just unpoison it in all cases.

llvm-svn: 197383
This commit is contained in:
Evgeniy Stepanov 2013-12-16 13:24:33 +00:00
parent c062b23ec2
commit 43fc44007d
2 changed files with 41 additions and 28 deletions

View File

@ -1061,6 +1061,27 @@ TEST(MemorySanitizer, gethostbyname_r) {
EXPECT_NOT_POISONED(err);
}
TEST(MemorySanitizer, gethostbyname_r_bad_host_name) {
char buf[2000];
struct hostent he;
struct hostent *result;
int err;
int res = gethostbyname_r("bad-host-name", &he, buf, sizeof(buf), &result, &err);
ASSERT_EQ(0, res);
ASSERT_EQ((struct hostent *)0, result);
EXPECT_NOT_POISONED(err);
}
TEST(MemorySanitizer, gethostbyname_r_erange) {
char buf[5];
struct hostent he;
struct hostent *result;
int err;
int res = gethostbyname_r("localhost", &he, buf, sizeof(buf), &result, &err);
ASSERT_EQ(ERANGE, res);
EXPECT_NOT_POISONED(err);
}
TEST(MemorySanitizer, gethostbyname2_r) {
char buf[2000];
struct hostent he;

View File

@ -1229,14 +1229,12 @@ INTERCEPTOR(int, gethostent_r, struct __sanitizer_hostent *ret, char *buf,
COMMON_INTERCEPTOR_ENTER(ctx, gethostent_r, ret, buf, buflen, result,
h_errnop);
int res = REAL(gethostent_r)(ret, buf, buflen, result, h_errnop);
if (res == 0) {
if (result) {
COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
if (*result) write_hostent(ctx, *result);
}
if (h_errnop)
COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h_errnop, sizeof(*h_errnop));
if (res == 0 && result) {
COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
if (*result) write_hostent(ctx, *result);
}
if (h_errnop)
COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h_errnop, sizeof(*h_errnop));
return res;
}
@ -1249,14 +1247,12 @@ INTERCEPTOR(int, gethostbyaddr_r, void *addr, int len, int type,
COMMON_INTERCEPTOR_READ_RANGE(ctx, addr, len);
int res = REAL(gethostbyaddr_r)(addr, len, type, ret, buf, buflen, result,
h_errnop);
if (res == 0) {
if (result) {
COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
if (*result) write_hostent(ctx, *result);
}
if (h_errnop)
COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h_errnop, sizeof(*h_errnop));
if (res == 0 && result) {
COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
if (*result) write_hostent(ctx, *result);
}
if (h_errnop)
COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h_errnop, sizeof(*h_errnop));
return res;
}
@ -1267,14 +1263,12 @@ INTERCEPTOR(int, gethostbyname_r, char *name, struct __sanitizer_hostent *ret,
COMMON_INTERCEPTOR_ENTER(ctx, gethostbyname_r, name, ret, buf, buflen, result,
h_errnop);
int res = REAL(gethostbyname_r)(name, ret, buf, buflen, result, h_errnop);
if (res == 0) {
if (result) {
COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
if (*result) write_hostent(ctx, *result);
}
if (h_errnop)
COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h_errnop, sizeof(*h_errnop));
if (res == 0 && result) {
COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
if (*result) write_hostent(ctx, *result);
}
if (h_errnop)
COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h_errnop, sizeof(*h_errnop));
return res;
}
@ -1286,14 +1280,12 @@ INTERCEPTOR(int, gethostbyname2_r, char *name, int af,
result, h_errnop);
int res =
REAL(gethostbyname2_r)(name, af, ret, buf, buflen, result, h_errnop);
if (res == 0) {
if (result) {
COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
if (*result) write_hostent(ctx, *result);
}
if (h_errnop)
COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h_errnop, sizeof(*h_errnop));
if (res == 0 && result) {
COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
if (*result) write_hostent(ctx, *result);
}
if (h_errnop)
COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h_errnop, sizeof(*h_errnop));
return res;
}
#define INIT_GETHOSTBYNAME_R \