diff --git a/compiler-rt/lib/msan/tests/msan_test.cc b/compiler-rt/lib/msan/tests/msan_test.cc index db7e55a96408..50a57fbde609 100644 --- a/compiler-rt/lib/msan/tests/msan_test.cc +++ b/compiler-rt/lib/msan/tests/msan_test.cc @@ -27,6 +27,7 @@ #include #include +#include #include #include #include @@ -1678,6 +1679,18 @@ TEST(MemorySanitizer, getpwnam_r_positive) { EXPECT_UMR(res = getpwnam_r(s, &pwd, buf, sizeof(buf), &pwdres)); } +TEST(MemorySanitizer, getgrnam_r) { + struct group grp; + struct group *grpres; + char buf[10000]; + int res = getgrnam_r("root", &grp, buf, sizeof(buf), &grpres); + assert(!res); + EXPECT_NOT_POISONED(grp.gr_name); + assert(grp.gr_name); + EXPECT_NOT_POISONED(grp.gr_name[0]); + EXPECT_NOT_POISONED(grp.gr_gid); +} + template static bool applySlt(T value, T shadow) { __msan_partial_poison(&value, &shadow, sizeof(T)); diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc b/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc index a42014373466..5baa271fc7c9 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc +++ b/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc @@ -429,7 +429,7 @@ SCANF_INTERCEPTOR_IMPL(__isoc99_sscanf, __isoc99_vsscanf, str, format) #define INIT_SCANF #endif -#if SANITIZER_INTERCEPT_GETPWNAM_GETPWUID +#if SANITIZER_INTERCEPT_GETPWNAM_AND_FRIENDS INTERCEPTOR(void *, getpwnam, const char *name) { void *ctx; COMMON_INTERCEPTOR_ENTER(ctx, getpwnam, name); @@ -447,15 +447,34 @@ INTERCEPTOR(void *, getpwuid, u32 uid) { COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, struct_passwd_sz); return res; } -#define INIT_GETPWNAM_GETPWUID \ - INTERCEPT_FUNCTION(getpwnam); \ - INTERCEPT_FUNCTION(getpwuid); +INTERCEPTOR(void *, getgrnam, const char *name) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, getgrnam, name); + COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1); + void *res = REAL(getgrnam)(name); + if (res != 0) + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, struct_group_sz); + return res; +} +INTERCEPTOR(void *, getgrgid, u32 gid) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, getgrgid, gid); + void *res = REAL(getgrgid)(gid); + if (res != 0) + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, struct_group_sz); + return res; +} +#define INIT_GETPWNAM_AND_FRIENDS \ + INTERCEPT_FUNCTION(getpwnam); \ + INTERCEPT_FUNCTION(getpwuid); \ + INTERCEPT_FUNCTION(getgrnam); \ + INTERCEPT_FUNCTION(getgrgid); #else -#define INIT_GETPWNAM_GETPWUID +#define INIT_GETPWNAM_AND_FRIENDS #endif -#if SANITIZER_INTERCEPT_GETPWNAM_R_GETPWUID_R +#if SANITIZER_INTERCEPT_GETPWNAM_R_AND_FRIENDS INTERCEPTOR(int, getpwnam_r, const char *name, void *pwd, char *buf, SIZE_T buflen, void **result) { void *ctx; @@ -479,11 +498,36 @@ INTERCEPTOR(int, getpwuid_r, u32 uid, void *pwd, } return res; } -#define INIT_GETPWNAM_R_GETPWUID_R \ - INTERCEPT_FUNCTION(getpwnam_r); \ - INTERCEPT_FUNCTION(getpwuid_r); +INTERCEPTOR(int, getgrnam_r, const char *name, void *grp, + char *buf, SIZE_T buflen, void **result) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, getgrnam_r, name, grp, buf, buflen, result); + COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1); + int res = REAL(getgrnam_r)(name, grp, buf, buflen, result); + if (!res) { + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, grp, struct_group_sz); + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, buflen); + } + return res; +} +INTERCEPTOR(int, getgrgid_r, u32 gid, void *grp, + char *buf, SIZE_T buflen, void **result) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, getgrgid_r, gid, grp, buf, buflen, result); + int res = REAL(getgrgid_r)(gid, grp, buf, buflen, result); + if (!res) { + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, grp, struct_group_sz); + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, buflen); + } + return res; +} +#define INIT_GETPWNAM_R_AND_FRIENDS \ + INTERCEPT_FUNCTION(getpwnam_r); \ + INTERCEPT_FUNCTION(getpwuid_r); \ + INTERCEPT_FUNCTION(getgrnam_r); \ + INTERCEPT_FUNCTION(getgrgid_r); #else -#define INIT_GETPWNAM_R_GETPWUID_R +#define INIT_GETPWNAM_R_AND_FRIENDS #endif @@ -667,8 +711,8 @@ INTERCEPTOR(int, wait4, int pid, int *status, int options, void *rusage) { INIT_SCANF; \ INIT_FREXP; \ INIT_FREXPF_FREXPL; \ - INIT_GETPWNAM_GETPWUID; \ - INIT_GETPWNAM_R_GETPWUID_R; \ + INIT_GETPWNAM_AND_FRIENDS; \ + INIT_GETPWNAM_R_AND_FRIENDS; \ INIT_CLOCK_GETTIME; \ INIT_GETITIMER; \ INIT_TIME; \ diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h b/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h index d1eb7245de9a..758ff9b9ec39 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h +++ b/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h @@ -58,8 +58,8 @@ # define SANITIZER_INTERCEPT_FREXP 1 # define SANITIZER_INTERCEPT_FREXPF_FREXPL SI_NOT_WINDOWS -# define SANITIZER_INTERCEPT_GETPWNAM_GETPWUID SI_NOT_WINDOWS -# define SANITIZER_INTERCEPT_GETPWNAM_R_GETPWUID_R \ +# 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_CLOCK_GETTIME SI_LINUX # define SANITIZER_INTERCEPT_GETITIMER SI_NOT_WINDOWS diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.cc b/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.cc index 889c1e51d7d6..262d50ae6faf 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.cc +++ b/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.cc @@ -20,6 +20,7 @@ #include "sanitizer_platform_limits_posix.h" #include +#include #include #include #include @@ -47,6 +48,7 @@ namespace __sanitizer { unsigned struct_rusage_sz = sizeof(struct rusage); unsigned struct_tm_sz = sizeof(struct tm); unsigned struct_passwd_sz = sizeof(struct passwd); + unsigned struct_group_sz = sizeof(struct group); unsigned siginfo_t_sz = sizeof(siginfo_t); unsigned struct_sigaction_sz = sizeof(struct sigaction); unsigned struct_itimerval_sz = sizeof(struct itimerval); diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.h b/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.h index 9da30af94340..60f1c3de32c0 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.h +++ b/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.h @@ -24,6 +24,7 @@ namespace __sanitizer { extern unsigned struct_rusage_sz; extern unsigned struct_tm_sz; extern unsigned struct_passwd_sz; + extern unsigned struct_group_sz; extern unsigned struct_sigaction_sz; extern unsigned siginfo_t_sz; extern unsigned struct_itimerval_sz; diff --git a/compiler-rt/lib/tsan/rtl/tsan_stat.cc b/compiler-rt/lib/tsan/rtl/tsan_stat.cc index d67b3226b3a6..cbf870f1ddab 100644 --- a/compiler-rt/lib/tsan/rtl/tsan_stat.cc +++ b/compiler-rt/lib/tsan/rtl/tsan_stat.cc @@ -289,8 +289,12 @@ void StatOutput(u64 *stat) { name[StatInt_frexpl] = " frexpl "; name[StatInt_getpwnam] = " getpwnam "; name[StatInt_getpwuid] = " getpwuid "; + name[StatInt_getgrnam] = " getgrnam "; + name[StatInt_getgrgid] = " getgrgid "; name[StatInt_getpwnam_r] = " getpwnam_r "; name[StatInt_getpwuid_r] = " getpwuid_r "; + name[StatInt_getgrnam_r] = " getgrnam_r "; + name[StatInt_getgrgid_r] = " getgrgid_r "; name[StatInt_clock_getres] = " clock_getres "; name[StatInt_clock_gettime] = " clock_gettime "; name[StatInt_clock_settime] = " clock_settime "; diff --git a/compiler-rt/lib/tsan/rtl/tsan_stat.h b/compiler-rt/lib/tsan/rtl/tsan_stat.h index 06e63c44e00a..da1dc9c33e3b 100644 --- a/compiler-rt/lib/tsan/rtl/tsan_stat.h +++ b/compiler-rt/lib/tsan/rtl/tsan_stat.h @@ -284,8 +284,12 @@ enum StatType { StatInt_frexpl, StatInt_getpwnam, StatInt_getpwuid, + StatInt_getgrnam, + StatInt_getgrgid, StatInt_getpwnam_r, StatInt_getpwuid_r, + StatInt_getgrnam_r, + StatInt_getgrgid_r, StatInt_clock_getres, StatInt_clock_gettime, StatInt_clock_settime,