[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