Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save cmb69/77ad17bf57c6ef35785476d5328b4b74 to your computer and use it in GitHub Desktop.
Save cmb69/77ad17bf57c6ef35785476d5328b4b74 to your computer and use it in GitHub Desktop.
Suggested patch for PHP bug #81726
From 0976bf346d6e4565ac9c3dfca8d431487601b6d0 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
`100`.
This issue has been reported by real_as3617 and gPayl0ad.
[1] <https://honno.dev/gzip-quine/>
---
ext/phar/phar.c | 16 +++++++++++-----
ext/phar/tests/bug81726.gz | Bin 0 -> 204 bytes
ext/phar/tests/bug81726.phpt | 14 ++++++++++++++
3 files changed, 25 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..d3e6225d16 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 = 100; // 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;
}
diff --git a/ext/phar/tests/bug81726.gz b/ext/phar/tests/bug81726.gz
new file mode 100644
index 0000000000000000000000000000000000000000..67b41ba3b6567fb242296fbb5db1504dd562c285
GIT binary patch
literal 204
zcmb2|=HOref&Yc2nR%&t=~WC25)9A(%i|Dt5_1=0XJBRc^&i0ka~VV!USk*QP&~o_
nktKo!bjW{@YyLCvGJN{)1lEBn)?BbahT(tZ|CMKe>QFcU?_ozX
literal 0
HcmV?d00001
diff --git a/ext/phar/tests/bug81726.phpt b/ext/phar/tests/bug81726.phpt
new file mode 100644
index 0000000000..11a148c28e
--- /dev/null
+++ b/ext/phar/tests/bug81726.phpt
@@ -0,0 +1,14 @@
+--TEST--
+Bug #81726 (phar wrapper: DOS when using quine gzip file)
+--SKIPIF--
+<?php
+if (!extension_loaded("phar")) die("skip phar extension not available");
+if (!extension_loaded("zlib")) die("skip zlib extension not available");
+?>
+--FILE--
+<?php
+var_dump(fopen("phar://" . __DIR__ . "/bug81726.gz", "r"));
+?>
+--EXPECTF--
+Warning: fopen(phar://%s): failed to open stream: unable to decompress gzipped phar archive "%s" in %s on line %d
+bool(false)
--
2.37.1.windows.1
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment