Skip to content

Commit 2aafa62

Browse files
committed
[𝘀𝗽𝗿] initial version
Created using spr 1.3.4
1 parent c0952a9 commit 2aafa62

File tree

4 files changed

+150
-0
lines changed

4 files changed

+150
-0
lines changed

compiler-rt/lib/msan/tests/msan_test.cpp

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4908,5 +4908,74 @@ TEST(MemorySanitizer, timer_create) {
49084908
EXPECT_POISONED(timer2);
49094909
timer_delete(timer);
49104910
}
4911+
4912+
TEST(MemorySanitizer, getservent_r) {
4913+
struct servent result_buf;
4914+
struct servent *result;
4915+
char buf[1024];
4916+
EXPECT_POISONED(result_buf);
4917+
EXPECT_POISONED(result);
4918+
EXPECT_POISONED(buf);
4919+
ASSERT_EQ(getservent_r(&result_buf, buf, sizeof(buf), &result), 0);
4920+
EXPECT_NOT_POISONED(result);
4921+
ASSERT_NE(result, nullptr);
4922+
EXPECT_NOT_POISONED(result_buf);
4923+
EXPECT_NOT_POISONED(buf);
4924+
}
4925+
4926+
TEST(MemorySanitizer, getservbyname_r) {
4927+
struct servent result_buf;
4928+
struct servent *result;
4929+
char buf[1024];
4930+
EXPECT_POISONED(result_buf);
4931+
EXPECT_POISONED(result);
4932+
EXPECT_POISONED(buf);
4933+
ASSERT_EQ(
4934+
getservbyname_r("ssh", nullptr, &result_buf, buf, sizeof(buf), &result),
4935+
0);
4936+
EXPECT_NOT_POISONED(result);
4937+
// If this fails, check /etc/services if "ssh" exists. I picked this because
4938+
// it should exist everywhere, if it doesn't, I am sorry. Disable the test
4939+
// then please.
4940+
ASSERT_NE(result, nullptr);
4941+
EXPECT_NOT_POISONED(result_buf);
4942+
EXPECT_NOT_POISONED(buf);
4943+
}
4944+
4945+
TEST(MemorySanitizer, getservbyname_r_unknown) {
4946+
struct servent result_buf;
4947+
struct servent *result;
4948+
char buf[1024];
4949+
EXPECT_POISONED(result_buf);
4950+
EXPECT_POISONED(result);
4951+
EXPECT_POISONED(buf);
4952+
ASSERT_EQ(getservbyname_r("invalidhadfuiasdhi", nullptr, &result_buf, buf,
4953+
sizeof(buf), &result),
4954+
0);
4955+
EXPECT_NOT_POISONED(result);
4956+
ASSERT_EQ(result, nullptr);
4957+
EXPECT_POISONED(result_buf);
4958+
EXPECT_POISONED(buf);
4959+
}
4960+
4961+
TEST(MemorySanitizer, getservbyport_r) {
4962+
struct servent result_buf;
4963+
struct servent *result;
4964+
char buf[1024];
4965+
EXPECT_POISONED(result_buf);
4966+
EXPECT_POISONED(result);
4967+
EXPECT_POISONED(buf);
4968+
ASSERT_EQ(getservbyport_r(htons(22), nullptr, &result_buf, buf, sizeof(buf),
4969+
&result),
4970+
0);
4971+
EXPECT_NOT_POISONED(result);
4972+
// If this fails, check /etc/services if "ssh" exists. I picked this because
4973+
// it should exist everywhere, if it doesn't, I am sorry. Disable the test
4974+
// then please.
4975+
ASSERT_NE(result, nullptr);
4976+
EXPECT_NOT_POISONED(result_buf);
4977+
EXPECT_NOT_POISONED(buf);
4978+
}
4979+
49114980
#endif
49124981
} // namespace

compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10279,6 +10279,71 @@ INTERCEPTOR(SSIZE_T, freadlink, int fd, char *buf, SIZE_T bufsiz) {
1027910279
# define INIT_FREADLINK
1028010280
#endif
1028110281

10282+
#if SANITIZER_INTERCEPT_GETSERVENT_R || SANITIZER_INTERCEPT_GETSERVBYNAME_R || \
10283+
SANITIZER_INTERCEPT_GETSERVBYPORT_R
10284+
10285+
UNUSED static void HandleGetServentReentrantResult(
10286+
void *ctx, int res, struct __sanitizer_servent *result_buf, char *buf,
10287+
SIZE_T buflen, struct __sanitizer_servent **result) {
10288+
if (res)
10289+
return;
10290+
COMMON_INTERCEPTOR_WRITE_RANGE(ctx, (char *)result, sizeof(void *));
10291+
if (*result) {
10292+
COMMON_INTERCEPTOR_WRITE_RANGE(ctx, (char *)*result,
10293+
sizeof(__sanitizer_servent));
10294+
COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, buflen);
10295+
}
10296+
}
10297+
10298+
#endif
10299+
10300+
#if SANITIZER_INTERCEPT_GETSERVENT_R
10301+
INTERCEPTOR(int, getservent_r, struct __sanitizer_servent *result_buf,
10302+
char *buf, SIZE_T buflen, struct __sanitizer_servent **result) {
10303+
void *ctx;
10304+
COMMON_INTERCEPTOR_ENTER(ctx, getservent_r, result_buf, buf, buflen, result);
10305+
int res = REAL(getservent_r)(result_buf, buf, buflen, result);
10306+
HandleGetServentReentrantResult(ctx, res, result_buf, buf, buflen, result);
10307+
return res;
10308+
}
10309+
# define INIT_GETSERVENT_R COMMON_INTERCEPT_FUNCTION(getservent_r)
10310+
#else
10311+
# define INIT_GETSERVENT_R
10312+
#endif
10313+
10314+
#if SANITIZER_INTERCEPT_GETSERVBYNAME_R
10315+
INTERCEPTOR(int, getservbyname_r, const char *name, const char *proto,
10316+
struct __sanitizer_servent *result_buf, char *buf, SIZE_T buflen,
10317+
struct __sanitizer_servent **result) {
10318+
void *ctx;
10319+
COMMON_INTERCEPTOR_ENTER(ctx, getservbyname_r, name, proto, result_buf, buf,
10320+
buflen, result);
10321+
COMMON_INTERCEPTOR_READ_STRING(ctx, name, internal_strlen(name));
10322+
int res = REAL(getservbyname_r)(name, proto, result_buf, buf, buflen, result);
10323+
HandleGetServentReentrantResult(ctx, res, result_buf, buf, buflen, result);
10324+
return res;
10325+
}
10326+
# define INIT_GETSERVBYNAME_R COMMON_INTERCEPT_FUNCTION(getservbyname_r)
10327+
#else
10328+
# define INIT_GETSERVBYNAME_R
10329+
#endif
10330+
10331+
#if SANITIZER_INTERCEPT_GETSERVBYPORT_R
10332+
INTERCEPTOR(int, getservbyport_r, int port, const char *proto,
10333+
struct __sanitizer_servent *result_buf, char *buf, SIZE_T buflen,
10334+
struct __sanitizer_servent **result) {
10335+
void *ctx;
10336+
COMMON_INTERCEPTOR_ENTER(ctx, getservbyport_r, port, proto, result_buf, buf,
10337+
buflen, result);
10338+
int res = REAL(getservbyport_r)(port, proto, result_buf, buf, buflen, result);
10339+
HandleGetServentReentrantResult(ctx, res, result_buf, buf, buflen, result);
10340+
return res;
10341+
}
10342+
# define INIT_GETSERVBYPORT_R COMMON_INTERCEPT_FUNCTION(getservbyport_r)
10343+
#else
10344+
# define INIT_GETSERVBYPORT_R
10345+
#endif
10346+
1028210347
#include "sanitizer_common_interceptors_netbsd_compat.inc"
1028310348

1028410349
namespace __sanitizer {
@@ -10604,4 +10669,7 @@ static void InitializeCommonInterceptors() {
1060410669
INIT_FREADLINK;
1060510670

1060610671
INIT___PRINTF_CHK;
10672+
INIT_GETSERVENT_R;
10673+
INIT_GETSERVBYNAME_R;
10674+
INIT_GETSERVBYPORT_R;
1060710675
}

compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -645,6 +645,10 @@ SANITIZER_WEAK_IMPORT void *aligned_alloc(__sanitizer::usize __alignment,
645645
# define SI_MAC_OS_DEPLOYMENT_MIN_13_00 0
646646
#endif
647647
#define SANITIZER_INTERCEPT_FREADLINK (SI_MAC && SI_MAC_OS_DEPLOYMENT_MIN_13_00)
648+
#define SANITIZER_INTERCEPT_GETSERVENT_R SI_GLIBC
649+
#define SANITIZER_INTERCEPT_GETSERVBYNAME_R SI_GLIBC
650+
#define SANITIZER_INTERCEPT_GETSERVBYPORT_R SI_GLIBC
651+
648652
// This macro gives a way for downstream users to override the above
649653
// interceptor macros irrespective of the platform they are on. They have
650654
// to do two things:

compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1509,6 +1509,15 @@ extern unsigned IOCTL_KIOCSOUND;
15091509
extern unsigned IOCTL_PIO_SCRNMAP;
15101510
#endif
15111511

1512+
# if SANITIZER_GLIBC
1513+
struct __sanitizer_servent {
1514+
char *s_name;
1515+
char **s_aliases;
1516+
int s_port;
1517+
char *s_proto;
1518+
};
1519+
# endif
1520+
15121521
extern const int si_SEGV_MAPERR;
15131522
extern const int si_SEGV_ACCERR;
15141523
} // namespace __sanitizer

0 commit comments

Comments
 (0)