diff options
author | Anatol Belski <ab@php.net> | 2018-08-06 22:35:11 +0200 |
---|---|---|
committer | Anatol Belski <ab@php.net> | 2018-08-30 19:33:07 +0200 |
commit | 7fb7869e13999f419787f56340ca4b4dbbb4eef8 (patch) | |
tree | 2bf4fbec7abebc5bf76ab8ae2941d8c92149a530 | |
parent | c1729272b17a1fe893d1a54e423d3b71470f3ee8 (diff) | |
download | php-git-7fb7869e13999f419787f56340ca4b4dbbb4eef8.tar.gz |
Fix stack underflow in phar
The checks can issue reads below and above the temporary buffer. A read
itself doesn't seem dangerous, but the condition result can be
arbitrary. Such reads have to be avoided. Likely this patch should be
backported.
(cherry picked from commit b053beee7efb64b8e439fb3639de839e615ba89c)
-rw-r--r-- | ext/phar/phar.c | 17 |
1 files changed, 7 insertions, 10 deletions
diff --git a/ext/phar/phar.c b/ext/phar/phar.c index 56fa253a6f..e053b6dd66 100644 --- a/ext/phar/phar.c +++ b/ext/phar/phar.c @@ -1832,27 +1832,24 @@ static int phar_analyze_path(const char *fname, const char *ext, int ext_len, in /* check for ".phar" in extension */ static int phar_check_str(const char *fname, const char *ext_str, int ext_len, int executable, int for_create) /* {{{ */ { - char test[51]; const char *pos; if (ext_len < 0 || ext_len >= 50) { return FAILURE; } - if (executable == 1) { - /* copy "." as well */ - memcpy(test, ext_str - 1, ext_len + 1); - test[ext_len + 1] = '\0'; /* executable phars must contain ".phar" as a valid extension (phar://.pharmy/oops is invalid) */ /* (phar://hi/there/.phar/oops is also invalid) */ - pos = strstr(test, ".phar"); + pos = strstr(ext_str, ".phar"); - if (pos && (*(pos - 1) != '/') - && (pos += 5) && (*pos == '\0' || *pos == '/' || *pos == '.')) { - return phar_analyze_path(fname, ext_str, ext_len, for_create); - } else { + if (!pos + || pos != ext_str && (*(pos - 1) == '/') + || (ext_len - (pos - ext_str)) < 5 + || !(pos += 5) + || !(*pos == '\0' || *pos == '/' || *pos == '.')) { return FAILURE; } + return phar_analyze_path(fname, ext_str, ext_len, for_create); } /* data phars need only contain a single non-"." to be valid */ |