Skip to content

Commit f852788

Browse files
committed
sljit/protexec: fix out-of-bounds stack write
In create_tempfile() we look for a suitable place to put the temporary file into and, among others, look at $TMPDIR. If the value of this environment variable exceeds the bounds of the local tmp_name[] buffer, we ignore it. However, we still change the value of 'tmp_name_len' which leads to follow-up errors. On debug builds this can lead to hitting the assertion as can be seen below: $ TMPDIR=$(perl -e 'print "A"x1024') ./bin/array_access Assertion failed at sljit_src/sljitProtExecAllocator.c:147 Aborted For non-debug builds, however, this can lead to a memory corruption, by abusing the fact that we change a trailing '/' to '\0' later on. With a sufficiently high enough value for 'tmp_name_len' this can corrupt stack frames up in the call chain. Fix this by setting 'tmp_name_len' only if value it is based on is found to be valid -- just like it was prior to commit 98323bd82218. Fixes: 98323bd82218 ("protexec: refactor create_tempfile() (#37)") Signed-off-by: Mathias Krause <[email protected]>
1 parent 0746b3d commit f852788

File tree

1 file changed

+10
-5
lines changed

1 file changed

+10
-5
lines changed

src/sljit/sljitProtExecAllocator.c

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,7 @@ static SLJIT_INLINE int create_tempfile(void)
107107
int fd;
108108
char tmp_name[256];
109109
size_t tmp_name_len = 0;
110+
size_t tmp_len;
110111
char *dir;
111112
struct stat st;
112113
#if defined(SLJIT_SINGLE_THREADED) && SLJIT_SINGLE_THREADED
@@ -125,18 +126,22 @@ static SLJIT_INLINE int create_tempfile(void)
125126
dir = secure_getenv("TMPDIR");
126127

127128
if (dir) {
128-
tmp_name_len = strlen(dir);
129-
if (tmp_name_len > 0 && tmp_name_len < sizeof(tmp_name)) {
130-
if ((stat(dir, &st) == 0) && S_ISDIR(st.st_mode))
129+
tmp_len = strlen(dir);
130+
if (tmp_len > 0 && tmp_len < sizeof(tmp_name)) {
131+
if ((stat(dir, &st) == 0) && S_ISDIR(st.st_mode)) {
131132
strcpy(tmp_name, dir);
133+
tmp_name_len = tmp_len;
134+
}
132135
}
133136
}
134137

135138
#ifdef P_tmpdir
136139
if (!tmp_name_len) {
137-
tmp_name_len = strlen(P_tmpdir);
138-
if (tmp_name_len > 0 && tmp_name_len < sizeof(tmp_name))
140+
tmp_len = strlen(P_tmpdir);
141+
if (tmp_len > 0 && tmp_len < sizeof(tmp_name)) {
139142
strcpy(tmp_name, P_tmpdir);
143+
tmp_name_len = tmp_len;
144+
}
140145
}
141146
#endif
142147
if (!tmp_name_len) {

0 commit comments

Comments
 (0)