-
Notifications
You must be signed in to change notification settings - Fork 15.1k
[sanitizer] Fix sanitizing glob_t when flags contain GLOB_DOOFFS #166468
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
|
@llvm/pr-subscribers-compiler-rt-sanitizer Author: Samuel Thibault (sthibaul) Changese.g. glob_t g; will reserve one NULL entry at the beginning of g.gl_pathv, in addition to the gl.gl_pathc results. Full diff: https://github.com/llvm/llvm-project/pull/166468.diff 1 Files Affected:
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc b/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc
index 24a8a2d4dc55b..8bb03f6d251fb 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc
@@ -2409,13 +2409,18 @@ INTERCEPTOR(int, timespec_get, struct __sanitizer_timespec *ts, int base) {
#endif
#if SANITIZER_INTERCEPT_GLOB
-static void unpoison_glob_t(void *ctx, __sanitizer_glob_t *pglob) {
+static void unpoison_glob_t(void *ctx, int flags, __sanitizer_glob_t *pglob) {
+ SIZE_T offs;
COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pglob, sizeof(*pglob));
+ if (flags & GLOB_DOOFFS)
+ offs = pglob->gl_offs;
+ else
+ offs = 0;
// +1 for NULL pointer at the end.
if (pglob->gl_pathv)
COMMON_INTERCEPTOR_WRITE_RANGE(
- ctx, pglob->gl_pathv, (pglob->gl_pathc + 1) * sizeof(*pglob->gl_pathv));
- for (SIZE_T i = 0; i < pglob->gl_pathc; ++i) {
+ ctx, pglob->gl_pathv, (offs + pglob->gl_pathc + 1) * sizeof(*pglob->gl_pathv));
+ for (SIZE_T i = offs; i < offs + pglob->gl_pathc; ++i) {
char *p = pglob->gl_pathv[i];
COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, internal_strlen(p) + 1);
}
@@ -2429,7 +2434,7 @@ INTERCEPTOR(int, glob, const char *pattern, int flags,
COMMON_INTERCEPTOR_ENTER(ctx, glob, pattern, flags, errfunc, pglob);
COMMON_INTERCEPTOR_READ_STRING(ctx, pattern, 0);
int res = REAL(glob)(pattern, flags, errfunc, pglob);
- if ((!res || res == glob_nomatch) && pglob) unpoison_glob_t(ctx, pglob);
+ if ((!res || res == glob_nomatch) && pglob) unpoison_glob_t(ctx, flags, pglob);
return res;
}
#else
@@ -2493,7 +2498,7 @@ INTERCEPTOR(int, glob, const char *pattern, int flags,
Swap(pglob->gl_stat, glob_copy.gl_stat);
}
pglob_copy = 0;
- if ((!res || res == glob_nomatch) && pglob) unpoison_glob_t(ctx, pglob);
+ if ((!res || res == glob_nomatch) && pglob) unpoison_glob_t(ctx, flags, pglob);
return res;
}
#endif // SANITIZER_SOLARIS
@@ -2529,7 +2534,7 @@ INTERCEPTOR(int, glob64, const char *pattern, int flags,
Swap(pglob->gl_stat, glob_copy.gl_stat);
}
pglob_copy = 0;
- if ((!res || res == glob_nomatch) && pglob) unpoison_glob_t(ctx, pglob);
+ if ((!res || res == glob_nomatch) && pglob) unpoison_glob_t(ctx, flags, pglob);
return res;
}
#define INIT_GLOB64 \
|
You can test this locally with the following command:git-clang-format --diff origin/main HEAD --extensions h,inc,cpp -- compiler-rt/test/sanitizer_common/TestCases/Posix/glob.cpp compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.h --diff_from_common_commit
View the diff from clang-format here.diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc b/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc
index 7729dde59..13ea1f15c 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc
@@ -2486,7 +2486,7 @@ static void unpoison_glob_t(void* ctx, int flags, __sanitizer_glob_t* pglob) {
}
}
-#if SANITIZER_SOLARIS
+# if SANITIZER_SOLARIS
INTERCEPTOR(int, glob, const char *pattern, int flags,
int (*errfunc)(const char *epath, int eerrno),
__sanitizer_glob_t *pglob) {
|
8a63aff to
715f002
Compare
|
Mmm, the formatting test asks me to change a line which my patch doesn't touch at all... |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for that patch!
Would it be possible to add a test in /sanitizer_common/ to cover the case?
|
I added a test, but didn't find how one is supposed to run tests in compiler-rt, make help only shows |
It allows to reserve some NULL entries at the beginning of g.gl_pathv, in addition to the gl.gl_pathc results.
e.g.
glob_t g;
memset(&g, 0, sizeof(g);
g.gl_offs = 1;
glob("*", GLOB_DOOFFS, NULL, &g);
will reserve one NULL entry at the beginning of g.gl_pathv, in addition to the gl.gl_pathc results.