mirror of
https://abf.rosa.ru/djam/php7.git
synced 2025-02-23 14:52:47 +00:00
72 lines
2.7 KiB
Diff
72 lines
2.7 KiB
Diff
From 404e8bdb68350931176a5bdc86fc417b34fb583d Mon Sep 17 00:00:00 2001
|
|
From: "Christoph M. Becker" <cmbecker69@gmx.de>
|
|
Date: Mon, 25 Jul 2022 15:58:59 +0200
|
|
Subject: [PATCH] Fix #81726: phar wrapper: DOS when using quine gzip file
|
|
|
|
The phar wrapper needs to uncompress the file; the uncompressed file
|
|
might be compressed, so the wrapper implementation loops. This raises
|
|
potential DOS issues regarding too deep or even infinite recursion (the
|
|
latter are called compressed file quines[1]). We avoid that by
|
|
introducing a recursion limit; we choose the somewhat arbitrary limit
|
|
`3`.
|
|
|
|
This issue has been reported by real_as3617 and gPayl0ad.
|
|
|
|
[1] <https://honno.dev/gzip-quine/>
|
|
---
|
|
NEWS | 1 +
|
|
ext/phar/phar.c | 16 +++++++++++-----
|
|
ext/phar/tests/bug81726.gz | Bin 0 -> 204 bytes
|
|
ext/phar/tests/bug81726.phpt | 14 ++++++++++++++
|
|
4 files changed, 26 insertions(+), 5 deletions(-)
|
|
create mode 100644 ext/phar/tests/bug81726.gz
|
|
create mode 100644 ext/phar/tests/bug81726.phpt
|
|
|
|
diff --git a/ext/phar/phar.c b/ext/phar/phar.c
|
|
index 7cb1b06363..4a761ef799 100644
|
|
--- a/ext/phar/phar.c
|
|
+++ b/ext/phar/phar.c
|
|
@@ -1584,7 +1584,8 @@ static int phar_open_from_fp(php_stream* fp, char *fname, size_t fname_len, char
|
|
const char zip_magic[] = "PK\x03\x04";
|
|
const char gz_magic[] = "\x1f\x8b\x08";
|
|
const char bz_magic[] = "BZh";
|
|
- char *pos, test = '\0';
|
|
+ char *pos;
|
|
+ int recursion_count = 3; // arbitrary limit to avoid too deep or even infinite recursion
|
|
const int window_size = 1024;
|
|
char buffer[1024 + sizeof(token)]; /* a 1024 byte window + the size of the halt_compiler token (moving window) */
|
|
const zend_long readsize = sizeof(buffer) - sizeof(token);
|
|
@@ -1612,8 +1613,7 @@ static int phar_open_from_fp(php_stream* fp, char *fname, size_t fname_len, char
|
|
MAPPHAR_ALLOC_FAIL("internal corruption of phar \"%s\" (truncated entry)")
|
|
}
|
|
|
|
- if (!test) {
|
|
- test = '\1';
|
|
+ if (recursion_count) {
|
|
pos = buffer+tokenlen;
|
|
if (!memcmp(pos, gz_magic, 3)) {
|
|
char err = 0;
|
|
@@ -1673,7 +1673,10 @@ static int phar_open_from_fp(php_stream* fp, char *fname, size_t fname_len, char
|
|
compression = PHAR_FILE_COMPRESSED_GZ;
|
|
|
|
/* now, start over */
|
|
- test = '\0';
|
|
+ if (!--recursion_count) {
|
|
+ MAPPHAR_ALLOC_FAIL("unable to decompress gzipped phar archive \"%s\"");
|
|
+ break;
|
|
+ }
|
|
continue;
|
|
} else if (!memcmp(pos, bz_magic, 3)) {
|
|
php_stream_filter *filter;
|
|
@@ -1711,7 +1714,10 @@ static int phar_open_from_fp(php_stream* fp, char *fname, size_t fname_len, char
|
|
compression = PHAR_FILE_COMPRESSED_BZ2;
|
|
|
|
/* now, start over */
|
|
- test = '\0';
|
|
+ if (!--recursion_count) {
|
|
+ MAPPHAR_ALLOC_FAIL("unable to decompress bzipped phar archive \"%s\"");
|
|
+ break;
|
|
+ }
|
|
continue;
|
|
}
|
|
|