Skip to content

Commit c31c95a

Browse files
committed
[sanitizer] Fix sanitizing glob_t when flags contain GLOB_DOOFFS
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.
1 parent 8f683c3 commit c31c95a

File tree

2 files changed

+16
-6
lines changed

2 files changed

+16
-6
lines changed

compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2468,13 +2468,19 @@ INTERCEPTOR(int, timespec_get, struct __sanitizer_timespec *ts, int base) {
24682468
#endif
24692469

24702470
#if SANITIZER_INTERCEPT_GLOB
2471-
static void unpoison_glob_t(void *ctx, __sanitizer_glob_t *pglob) {
2471+
static void unpoison_glob_t(void* ctx, int flags, __sanitizer_glob_t* pglob) {
2472+
SIZE_T offs = 0;
24722473
COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pglob, sizeof(*pglob));
2474+
# ifdef __SANITIZER_GLOB_DOOFFS
2475+
if (flags & __SANITIZER_GLOB_DOOFFS)
2476+
offs = pglob->gl_offs;
2477+
# endif
24732478
// +1 for NULL pointer at the end.
24742479
if (pglob->gl_pathv)
24752480
COMMON_INTERCEPTOR_WRITE_RANGE(
2476-
ctx, pglob->gl_pathv, (pglob->gl_pathc + 1) * sizeof(*pglob->gl_pathv));
2477-
for (SIZE_T i = 0; i < pglob->gl_pathc; ++i) {
2481+
ctx, pglob->gl_pathv,
2482+
(offs + pglob->gl_pathc + 1) * sizeof(*pglob->gl_pathv));
2483+
for (SIZE_T i = offs; i < offs + pglob->gl_pathc; ++i) {
24782484
char *p = pglob->gl_pathv[i];
24792485
COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, internal_strlen(p) + 1);
24802486
}
@@ -2488,7 +2494,8 @@ INTERCEPTOR(int, glob, const char *pattern, int flags,
24882494
COMMON_INTERCEPTOR_ENTER(ctx, glob, pattern, flags, errfunc, pglob);
24892495
COMMON_INTERCEPTOR_READ_STRING(ctx, pattern, 0);
24902496
int res = REAL(glob)(pattern, flags, errfunc, pglob);
2491-
if ((!res || res == glob_nomatch) && pglob) unpoison_glob_t(ctx, pglob);
2497+
if ((!res || res == glob_nomatch) && pglob)
2498+
unpoison_glob_t(ctx, flags, pglob);
24922499
return res;
24932500
}
24942501
#else
@@ -2552,7 +2559,8 @@ INTERCEPTOR(int, glob, const char *pattern, int flags,
25522559
Swap(pglob->gl_stat, glob_copy.gl_stat);
25532560
}
25542561
pglob_copy = 0;
2555-
if ((!res || res == glob_nomatch) && pglob) unpoison_glob_t(ctx, pglob);
2562+
if ((!res || res == glob_nomatch) && pglob)
2563+
unpoison_glob_t(ctx, flags, pglob);
25562564
return res;
25572565
}
25582566
#endif // SANITIZER_SOLARIS
@@ -2588,7 +2596,8 @@ INTERCEPTOR(int, glob64, const char *pattern, int flags,
25882596
Swap(pglob->gl_stat, glob_copy.gl_stat);
25892597
}
25902598
pglob_copy = 0;
2591-
if ((!res || res == glob_nomatch) && pglob) unpoison_glob_t(ctx, pglob);
2599+
if ((!res || res == glob_nomatch) && pglob)
2600+
unpoison_glob_t(ctx, flags, pglob);
25922601
return res;
25932602
}
25942603
#define INIT_GLOB64 \

compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -872,6 +872,7 @@ struct __sanitizer_glob_t {
872872
int (*gl_lstat)(const char *, void *);
873873
int (*gl_stat)(const char *, void *);
874874
};
875+
# define __SANITIZER_GLOB_DOOFFS (1 << 3)
875876
# endif // SANITIZER_LINUX
876877

877878
# if SANITIZER_LINUX

0 commit comments

Comments
 (0)