[compiler-rt] r208773 - [sanitizer] Fix crash in getgrnam_r and similar interceptors.
Evgeniy Stepanov
eugeni.stepanov at gmail.com
Wed May 14 05:32:41 PDT 2014
Author: eugenis
Date: Wed May 14 07:32:40 2014
New Revision: 208773
URL: http://llvm.org/viewvc/llvm-project?rev=208773&view=rev
Log:
[sanitizer] Fix crash in getgrnam_r and similar interceptors.
When no matching record is found, getgrnam_r return 0 but sets result to NULL.
Should fix PR19734.
Added:
compiler-rt/trunk/test/sanitizer_common/TestCases/Linux/getpwnam_r_invalid_user.cc (with props)
Modified:
compiler-rt/trunk/lib/sanitizer_common/sanitizer_common_interceptors.inc
Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_common_interceptors.inc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_common_interceptors.inc?rev=208773&r1=208772&r2=208773&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_common_interceptors.inc (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_common_interceptors.inc Wed May 14 07:32:40 2014
@@ -1071,7 +1071,7 @@ INTERCEPTOR(int, getpwnam_r, const char
COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1);
int res = REAL(getpwnam_r)(name, pwd, buf, buflen, result);
if (!res) {
- unpoison_passwd(ctx, pwd);
+ if (result && *result) unpoison_passwd(ctx, *result);
COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, buflen);
}
if (result) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
@@ -1083,7 +1083,7 @@ INTERCEPTOR(int, getpwuid_r, u32 uid, __
COMMON_INTERCEPTOR_ENTER(ctx, getpwuid_r, uid, pwd, buf, buflen, result);
int res = REAL(getpwuid_r)(uid, pwd, buf, buflen, result);
if (!res) {
- unpoison_passwd(ctx, pwd);
+ if (result && *result) unpoison_passwd(ctx, *result);
COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, buflen);
}
if (result) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
@@ -1096,7 +1096,7 @@ INTERCEPTOR(int, getgrnam_r, const char
COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1);
int res = REAL(getgrnam_r)(name, grp, buf, buflen, result);
if (!res) {
- unpoison_group(ctx, grp);
+ if (result && *result) unpoison_group(ctx, *result);
COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, buflen);
}
if (result) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
@@ -1108,7 +1108,7 @@ INTERCEPTOR(int, getgrgid_r, u32 gid, __
COMMON_INTERCEPTOR_ENTER(ctx, getgrgid_r, gid, grp, buf, buflen, result);
int res = REAL(getgrgid_r)(gid, grp, buf, buflen, result);
if (!res) {
- unpoison_group(ctx, grp);
+ if (result && *result) unpoison_group(ctx, *result);
COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, buflen);
}
if (result) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
@@ -1174,7 +1174,7 @@ INTERCEPTOR(int, getpwent_r, __sanitizer
COMMON_INTERCEPTOR_ENTER(ctx, getpwent_r, pwbuf, buf, buflen, pwbufp);
int res = REAL(getpwent_r)(pwbuf, buf, buflen, pwbufp);
if (!res) {
- unpoison_passwd(ctx, pwbuf);
+ if (pwbufp && *pwbufp) unpoison_passwd(ctx, *pwbufp);
COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, buflen);
}
if (pwbufp) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwbufp, sizeof(*pwbufp));
@@ -1186,7 +1186,7 @@ INTERCEPTOR(int, fgetpwent_r, void *fp,
COMMON_INTERCEPTOR_ENTER(ctx, fgetpwent_r, fp, pwbuf, buf, buflen, pwbufp);
int res = REAL(fgetpwent_r)(fp, pwbuf, buf, buflen, pwbufp);
if (!res) {
- unpoison_passwd(ctx, pwbuf);
+ if (pwbufp && *pwbufp) unpoison_passwd(ctx, *pwbufp);
COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, buflen);
}
if (pwbufp) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwbufp, sizeof(*pwbufp));
@@ -1198,7 +1198,7 @@ INTERCEPTOR(int, getgrent_r, __sanitizer
COMMON_INTERCEPTOR_ENTER(ctx, getgrent_r, pwbuf, buf, buflen, pwbufp);
int res = REAL(getgrent_r)(pwbuf, buf, buflen, pwbufp);
if (!res) {
- unpoison_group(ctx, pwbuf);
+ if (pwbufp && *pwbufp) unpoison_group(ctx, *pwbufp);
COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, buflen);
}
if (pwbufp) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwbufp, sizeof(*pwbufp));
@@ -1210,7 +1210,7 @@ INTERCEPTOR(int, fgetgrent_r, void *fp,
COMMON_INTERCEPTOR_ENTER(ctx, fgetgrent_r, fp, pwbuf, buf, buflen, pwbufp);
int res = REAL(fgetgrent_r)(fp, pwbuf, buf, buflen, pwbufp);
if (!res) {
- unpoison_group(ctx, pwbuf);
+ if (pwbufp && *pwbufp) unpoison_group(ctx, *pwbufp);
COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, buflen);
}
if (pwbufp) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwbufp, sizeof(*pwbufp));
Added: compiler-rt/trunk/test/sanitizer_common/TestCases/Linux/getpwnam_r_invalid_user.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/sanitizer_common/TestCases/Linux/getpwnam_r_invalid_user.cc?rev=208773&view=auto
==============================================================================
--- compiler-rt/trunk/test/sanitizer_common/TestCases/Linux/getpwnam_r_invalid_user.cc (added)
+++ compiler-rt/trunk/test/sanitizer_common/TestCases/Linux/getpwnam_r_invalid_user.cc Wed May 14 07:32:40 2014
@@ -0,0 +1,19 @@
+// Regression test for a crash in getpwnam_r and similar interceptors.
+// RUN: %clangxx -O0 -g %s -o %t && %run %t
+
+#include <assert.h>
+#include <pwd.h>
+#include <signal.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+int main(void) {
+ struct passwd pwd;
+ struct passwd *pwdres;
+ char buf[10000];
+ int res = getpwnam_r("no-such-user", &pwd, buf, sizeof(buf), &pwdres);
+ assert(res == 0);
+ assert(pwdres == 0);
+ return 0;
+}
Propchange: compiler-rt/trunk/test/sanitizer_common/TestCases/Linux/getpwnam_r_invalid_user.cc
------------------------------------------------------------------------------
svn:eol-style = LF
More information about the llvm-commits
mailing list