[sanitizer] Intercept getpwent/getgrent.

llvm-svn: 205000
This commit is contained in:
Evgeniy Stepanov 2014-03-28 10:56:07 +00:00
parent ea1f8fb775
commit 74e77756ef
3 changed files with 132 additions and 0 deletions

View File

@ -3125,6 +3125,54 @@ TEST(MemorySanitizer, getgrnam_r) {
EXPECT_NOT_POISONED(grpres);
}
TEST(MemorySanitizer, getpwent) {
setpwent();
struct passwd *p = getpwent();
ASSERT_TRUE(p != NULL);
EXPECT_NOT_POISONED(p->pw_name);
ASSERT_TRUE(p->pw_name != NULL);
EXPECT_NOT_POISONED(p->pw_name[0]);
EXPECT_NOT_POISONED(p->pw_uid);
}
TEST(MemorySanitizer, getpwent_r) {
struct passwd pwd;
struct passwd *pwdres;
char buf[10000];
setpwent();
int res = getpwent_r(&pwd, buf, sizeof(buf), &pwdres);
ASSERT_EQ(0, res);
EXPECT_NOT_POISONED(pwd.pw_name);
ASSERT_TRUE(pwd.pw_name != NULL);
EXPECT_NOT_POISONED(pwd.pw_name[0]);
EXPECT_NOT_POISONED(pwd.pw_uid);
EXPECT_NOT_POISONED(pwdres);
}
TEST(MemorySanitizer, getgrent) {
setgrent();
struct group *p = getgrent();
ASSERT_TRUE(p != NULL);
EXPECT_NOT_POISONED(p->gr_name);
ASSERT_TRUE(p->gr_name != NULL);
EXPECT_NOT_POISONED(p->gr_name[0]);
EXPECT_NOT_POISONED(p->gr_gid);
}
TEST(MemorySanitizer, getgrent_r) {
struct group grp;
struct group *grpres;
char buf[10000];
setgrent();
int res = getgrent_r(&grp, buf, sizeof(buf), &grpres);
ASSERT_EQ(0, res);
EXPECT_NOT_POISONED(grp.gr_name);
ASSERT_TRUE(grp.gr_name != NULL);
EXPECT_NOT_POISONED(grp.gr_name[0]);
EXPECT_NOT_POISONED(grp.gr_gid);
EXPECT_NOT_POISONED(grpres);
}
TEST(MemorySanitizer, getgroups) {
int n = getgroups(0, 0);
gid_t *gids = new gid_t[n];

View File

@ -1012,6 +1012,86 @@ INTERCEPTOR(int, getgrgid_r, u32 gid, void *grp, char *buf, SIZE_T buflen,
#define INIT_GETPWNAM_R_AND_FRIENDS
#endif
#if SANITIZER_INTERCEPT_GETPWENT
INTERCEPTOR(void *, getpwent, int dummy) {
void *ctx;
COMMON_INTERCEPTOR_ENTER(ctx, getpwent, dummy);
void *res = REAL(getpwent)(dummy);
if (res != 0) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, struct_passwd_sz);
return res;
}
INTERCEPTOR(void *, getgrent, int dummy) {
void *ctx;
COMMON_INTERCEPTOR_ENTER(ctx, getgrent, dummy);
void *res = REAL(getgrent)(dummy);
if (res != 0) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, struct_group_sz);
return res;
}
#define INIT_GETPWENT \
COMMON_INTERCEPT_FUNCTION(getpwent); \
COMMON_INTERCEPT_FUNCTION(getgrent);
#else
#define INIT_GETPWENT
#endif
#if SANITIZER_INTERCEPT_GETPWENT_R
INTERCEPTOR(int, getpwent_r, void *pwbuf, char *buf, SIZE_T buflen,
void **pwbufp) {
void *ctx;
COMMON_INTERCEPTOR_ENTER(ctx, getpwent_r, pwbuf, buf, buflen, pwbufp);
int res = REAL(getpwent_r)(pwbuf, buf, buflen, pwbufp);
if (!res) {
COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwbuf, struct_passwd_sz);
COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, buflen);
}
if (pwbufp) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwbufp, sizeof(*pwbufp));
return res;
}
INTERCEPTOR(int, fgetpwent_r, void *fp, void *pwbuf, char *buf, SIZE_T buflen,
void **pwbufp) {
void *ctx;
COMMON_INTERCEPTOR_ENTER(ctx, fgetpwent_r, fp, pwbuf, buf, buflen, pwbufp);
int res = REAL(fgetpwent_r)(fp, pwbuf, buf, buflen, pwbufp);
if (!res) {
COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwbuf, struct_passwd_sz);
COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, buflen);
}
if (pwbufp) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwbufp, sizeof(*pwbufp));
return res;
}
INTERCEPTOR(int, getgrent_r, void *pwbuf, char *buf, SIZE_T buflen,
void **pwbufp) {
void *ctx;
COMMON_INTERCEPTOR_ENTER(ctx, getgrent_r, pwbuf, buf, buflen, pwbufp);
int res = REAL(getgrent_r)(pwbuf, buf, buflen, pwbufp);
if (!res) {
COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwbuf, struct_group_sz);
COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, buflen);
}
if (pwbufp) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwbufp, sizeof(*pwbufp));
return res;
}
INTERCEPTOR(int, fgetgrent_r, void *fp, void *pwbuf, char *buf, SIZE_T buflen,
void **pwbufp) {
void *ctx;
COMMON_INTERCEPTOR_ENTER(ctx, fgetgrent_r, fp, pwbuf, buf, buflen, pwbufp);
int res = REAL(fgetgrent_r)(fp, pwbuf, buf, buflen, pwbufp);
if (!res) {
COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwbuf, struct_group_sz);
COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, buflen);
}
if (pwbufp) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwbufp, sizeof(*pwbufp));
return res;
}
#define INIT_GETPWENT_R \
COMMON_INTERCEPT_FUNCTION(getpwent_r); \
COMMON_INTERCEPT_FUNCTION(fgetpwent_r); \
COMMON_INTERCEPT_FUNCTION(getgrent_r); \
COMMON_INTERCEPT_FUNCTION(fgetgrent_r);
#else
#define INIT_GETPWENT_R
#endif
#if SANITIZER_INTERCEPT_CLOCK_GETTIME
INTERCEPTOR(int, clock_getres, u32 clk_id, void *tp) {
void *ctx;
@ -3541,6 +3621,8 @@ INTERCEPTOR(int, ftime, __sanitizer_timeb *tp) {
INIT_FREXPF_FREXPL; \
INIT_GETPWNAM_AND_FRIENDS; \
INIT_GETPWNAM_R_AND_FRIENDS; \
INIT_GETPWENT; \
INIT_GETPWENT_R; \
INIT_CLOCK_GETTIME; \
INIT_GETITIMER; \
INIT_TIME; \

View File

@ -88,6 +88,8 @@
#define SANITIZER_INTERCEPT_GETPWNAM_AND_FRIENDS SI_NOT_WINDOWS
#define SANITIZER_INTERCEPT_GETPWNAM_R_AND_FRIENDS \
SI_MAC || SI_LINUX_NOT_ANDROID
#define SANITIZER_INTERCEPT_GETPWENT SI_NOT_WINDOWS
#define SANITIZER_INTERCEPT_GETPWENT_R SI_LINUX_NOT_ANDROID
#define SANITIZER_INTERCEPT_CLOCK_GETTIME SI_LINUX
#define SANITIZER_INTERCEPT_GETITIMER SI_NOT_WINDOWS
#define SANITIZER_INTERCEPT_TIME SI_NOT_WINDOWS