Skip to content

Commit b00f8f2

Browse files
committed
Merge branch 'PHP-5.6' into PHP-7.0
* PHP-5.6: fix #72519, possible OOB using imagegif fix #72512, invalid read or write for palette image when invalid transparent index is used Apparently some envs miss SIZE_MAX Fix tests Fix bug #72618: NULL Pointer Dereference in exif_process_user_comment Partial fix for bug #72613 - do not treat negative returns from bz2 as size_t Fix bug #72606: heap-buffer-overflow (write) simplestring_addn simplestring.c Fix for bug #72558, Integer overflow error within _gdContributionsAlloc() Fix bug #72603: Out of bound read in exif_process_IFD_in_MAKERNOTE Fix bug #72562 - destroy var_hash properly Fix bug #72533 (locale_accept_from_http out-of-bounds access) Fix fir bug #72520 Fix for bug #72513 Fix for bug #72513 CS fix and comments with bug ID Fix for HTTP_PROXY issue. 5.6.24RC1 add tests for bug #72512 Fixed bug #72512 gdImageTrueColorToPaletteBody allows arbitrary write/read access Fixed bug #72479 - same as #72434 Conflicts: Zend/zend_virtual_cwd.c ext/bz2/bz2.c ext/exif/exif.c ext/session/session.c ext/snmp/snmp.c ext/standard/basic_functions.c main/SAPI.c main/php_variables.c
2 parents e9a58be + 4d0565b commit b00f8f2

23 files changed

Lines changed: 358 additions & 81 deletions

ext/exif/exif.c

Lines changed: 31 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2604,6 +2604,7 @@ static int exif_process_user_comment(image_info_type *ImageInfo, char **pszInfoP
26042604
*pszEncoding = NULL;
26052605
/* Copy the comment */
26062606
if (ByteCount>=8) {
2607+
const zend_encoding *from, *to;
26072608
if (!memcmp(szValuePtr, "UNICODE\0", 8)) {
26082609
*pszEncoding = estrdup((const char*)szValuePtr);
26092610
szValuePtr = szValuePtr+8;
@@ -2624,15 +2625,16 @@ static int exif_process_user_comment(image_info_type *ImageInfo, char **pszInfoP
26242625
} else {
26252626
decode = ImageInfo->decode_unicode_le;
26262627
}
2628+
to = zend_multibyte_fetch_encoding(ImageInfo->encode_unicode);
2629+
from = zend_multibyte_fetch_encoding(decode);
26272630
/* XXX this will fail again if encoding_converter returns on error something different than SIZE_MAX */
2628-
if (zend_multibyte_encoding_converter(
2631+
if (!to || !from || zend_multibyte_encoding_converter(
26292632
(unsigned char**)pszInfoPtr,
26302633
&len,
26312634
(unsigned char*)szValuePtr,
26322635
ByteCount,
2633-
zend_multibyte_fetch_encoding(ImageInfo->encode_unicode),
2634-
zend_multibyte_fetch_encoding(decode)
2635-
) == (size_t)-1) {
2636+
to,
2637+
from) == (size_t)-1) {
26362638
len = exif_process_string_raw(pszInfoPtr, szValuePtr, ByteCount);
26372639
}
26382640
return len;
@@ -2646,14 +2648,15 @@ static int exif_process_user_comment(image_info_type *ImageInfo, char **pszInfoP
26462648
szValuePtr = szValuePtr+8;
26472649
ByteCount -= 8;
26482650
/* XXX this will fail again if encoding_converter returns on error something different than SIZE_MAX */
2649-
if (zend_multibyte_encoding_converter(
2651+
to = zend_multibyte_fetch_encoding(ImageInfo->encode_jis);
2652+
from = zend_multibyte_fetch_encoding(ImageInfo->motorola_intel ? ImageInfo->decode_jis_be : ImageInfo->decode_jis_le);
2653+
if (!to || !from || zend_multibyte_encoding_converter(
26502654
(unsigned char**)pszInfoPtr,
26512655
&len,
26522656
(unsigned char*)szValuePtr,
26532657
ByteCount,
2654-
zend_multibyte_fetch_encoding(ImageInfo->encode_jis),
2655-
zend_multibyte_fetch_encoding(ImageInfo->motorola_intel ? ImageInfo->decode_jis_be : ImageInfo->decode_jis_le)
2656-
) == (size_t)-1) {
2658+
to,
2659+
from) == (size_t)-1) {
26572660
len = exif_process_string_raw(pszInfoPtr, szValuePtr, ByteCount);
26582661
}
26592662
return len;
@@ -2723,6 +2726,12 @@ static int exif_process_IFD_in_MAKERNOTE(image_info_type *ImageInfo, char * valu
27232726
break;
27242727
}
27252728

2729+
if (maker_note->offset >= value_len) {
2730+
/* Do not go past the value end */
2731+
exif_error_docref("exif_read_data#error_ifd" EXIFERR_CC, ImageInfo, E_WARNING, "IFD data too short: 0x%04X offset 0x%04X", value_len, maker_note->offset);
2732+
return FALSE;
2733+
}
2734+
27262735
dir_start = value_ptr + maker_note->offset;
27272736

27282737
#ifdef EXIF_DEBUG
@@ -2751,10 +2760,19 @@ static int exif_process_IFD_in_MAKERNOTE(image_info_type *ImageInfo, char * valu
27512760
offset_base = value_ptr;
27522761
break;
27532762
case MN_OFFSET_GUESS:
2763+
if (maker_note->offset + 10 + 4 >= value_len) {
2764+
/* Can not read dir_start+10 since it's beyond value end */
2765+
exif_error_docref("exif_read_data#error_ifd" EXIFERR_CC, ImageInfo, E_WARNING, "IFD data too short: 0x%04X", value_len);
2766+
return FALSE;
2767+
}
27542768
offset_diff = 2 + NumDirEntries*12 + 4 - php_ifd_get32u(dir_start+10, ImageInfo->motorola_intel);
27552769
#ifdef EXIF_DEBUG
27562770
exif_error_docref(NULL EXIFERR_CC, ImageInfo, E_NOTICE, "Using automatic offset correction: 0x%04X", ((int)dir_start-(int)offset_base+maker_note->offset+displacement) + offset_diff);
27572771
#endif
2772+
if (offset_diff < 0 || offset_diff >= value_len ) {
2773+
exif_error_docref("exif_read_data#error_ifd" EXIFERR_CC, ImageInfo, E_WARNING, "IFD data bad offset: 0x%04X length 0x%04X", offset_diff, value_len);
2774+
return FALSE;
2775+
}
27582776
offset_base = value_ptr + offset_diff;
27592777
break;
27602778
default:
@@ -2763,7 +2781,7 @@ static int exif_process_IFD_in_MAKERNOTE(image_info_type *ImageInfo, char * valu
27632781
}
27642782

27652783
if ((2+NumDirEntries*12) > value_len) {
2766-
exif_error_docref("exif_read_data#error_ifd" EXIFERR_CC, ImageInfo, E_WARNING, "Illegal IFD size: 2 + x%04X*12 = x%04X > x%04X", NumDirEntries, 2+NumDirEntries*12, value_len);
2784+
exif_error_docref("exif_read_data#error_ifd" EXIFERR_CC, ImageInfo, E_WARNING, "Illegal IFD size: 2 + 0x%04X*12 = 0x%04X > 0x%04X", NumDirEntries, 2+NumDirEntries*12, value_len);
27672785
return FALSE;
27682786
}
27692787

@@ -3049,7 +3067,10 @@ static int exif_process_IFD_TAG(image_info_type *ImageInfo, char *dir_entry, cha
30493067
break;
30503068

30513069
case TAG_MAKER_NOTE:
3052-
exif_process_IFD_in_MAKERNOTE(ImageInfo, value_ptr, byte_count, offset_base, IFDlength, displacement);
3070+
if (!exif_process_IFD_in_MAKERNOTE(ImageInfo, value_ptr, byte_count, offset_base, IFDlength, displacement)) {
3071+
EFREE_IF(outside);
3072+
return FALSE;
3073+
}
30533074
break;
30543075

30553076
case TAG_EXIF_IFD_POINTER:

ext/exif/tests/bug54002.phpt

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,4 @@ exif_read_data(__DIR__ . '/bug54002_2.jpeg');
1313
--EXPECTF--
1414
Warning: exif_read_data(bug54002_1.jpeg): Process tag(x0205=UndefinedTa): Illegal byte_count in %sbug54002.php on line %d
1515

16-
Warning: exif_read_data(bug54002_1.jpeg): Process tag(xA000=FlashPixVer): Illegal pointer offset(%s) in %sbug54002.php on line %d
17-
18-
Warning: exif_read_data(bug54002_2.jpeg): Process tag(x0205=UndefinedTa): Illegal byte_count in %sbug54002.php on line %d
19-
20-
Warning: exif_read_data(bug54002_2.jpeg): Process tag(xA000=FlashPixVer): Illegal pointer offset(%s) in %sbug54002.php on line %d
16+
Warning: exif_read_data(bug54002_2.jpeg): Process tag(x0205=UndefinedTa): Illegal byte_count in %sbug54002.php on line %d

ext/exif/tests/bug62523_2.phpt

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,9 @@ echo "Test\n";
1010
var_dump(count(exif_read_data(__DIR__."/bug62523_2.jpg")));
1111
?>
1212
Done
13-
--EXPECT--
13+
--EXPECTF--
1414
Test
15-
int(76)
15+
16+
Warning: exif_read_data(bug62523_2.jpg): IFD data bad offset: 0xADB23672 length 0x0D94 in %s/bug62523_2.php on line %d
17+
int(30)
1618
Done

ext/exif/tests/bug72603.jpeg

3.62 KB
Loading

ext/exif/tests/bug72603.phpt

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
--TEST--
2+
Bug #72603 (Out of bound read in exif_process_IFD_in_MAKERNOTE)
3+
--SKIPIF--
4+
<?php if (!extension_loaded('exif')) print 'skip exif extension not available';?>
5+
--FILE--
6+
<?php
7+
var_dump(count(exif_read_data(dirname(__FILE__) . "/bug72603.jpeg")));
8+
?>
9+
--EXPECTF--
10+
Warning: exif_read_data(bug72603.jpeg): IFD data bad offset: 0x058C length 0x001C in %s/bug72603.php on line %d
11+
int(13)

ext/exif/tests/bug72618.jpg

3.62 KB
Loading

ext/exif/tests/bug72618.phpt

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
--TEST--
2+
Bug 72618 (NULL Pointer Dereference in exif_process_user_comment)
3+
--SKIPIF--
4+
<?php if (!extension_loaded('exif')) print 'skip exif extension not available';?>
5+
--FILE--
6+
<?php
7+
var_dump(count(exif_read_data(dirname(__FILE__) . "/bug72618.jpg")));
8+
?>
9+
--EXPECTF--
10+
Warning: exif_read_data(bug72618.jpg): IFD data bad offset: 0x058E length 0x0030 in %s/bug72618.php on line %d
11+
int(13)

ext/gd/libgd/gd.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -188,7 +188,7 @@ gdImagePtr gdImageCreateTrueColor (int sx, int sy)
188188
return NULL;
189189
}
190190

191-
if (overflow2(sizeof(int), sx)) {
191+
if (overflow2(sizeof(int *), sx)) {
192192
return NULL;
193193
}
194194

ext/gd/libgd/gd_interpolation.c

Lines changed: 69 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -879,20 +879,39 @@ int getPixelInterpolated(gdImagePtr im, const double x, const double y, const in
879879
static inline LineContribType * _gdContributionsAlloc(unsigned int line_length, unsigned int windows_size)
880880
{
881881
unsigned int u = 0;
882-
LineContribType *res;
882+
LineContribType *res;
883+
int overflow_error = 0;
883884

884885
res = (LineContribType *) gdMalloc(sizeof(LineContribType));
885886
if (!res) {
886887
return NULL;
887888
}
888-
res->WindowSize = windows_size;
889-
res->LineLength = line_length;
890-
res->ContribRow = (ContributionType *) gdMalloc(line_length * sizeof(ContributionType));
891-
892-
for (u = 0 ; u < line_length ; u++) {
893-
res->ContribRow[u].Weights = (double *) gdMalloc(windows_size * sizeof(double));
894-
}
895-
return res;
889+
res->WindowSize = windows_size;
890+
res->LineLength = line_length;
891+
if (overflow2(line_length, sizeof(ContributionType))) {
892+
return NULL;
893+
}
894+
res->ContribRow = (ContributionType *) gdMalloc(line_length * sizeof(ContributionType));
895+
if (res->ContribRow == NULL) {
896+
gdFree(res);
897+
return NULL;
898+
}
899+
for (u = 0 ; u < line_length ; u++) {
900+
if (overflow2(windows_size, sizeof(double))) {
901+
overflow_error = 1;
902+
} else {
903+
res->ContribRow[u].Weights = (double *) gdMalloc(windows_size * sizeof(double));
904+
}
905+
if (overflow_error == 1 || res->ContribRow[u].Weights == NULL) {
906+
u--;
907+
while (u >= 0) {
908+
gdFree(res->ContribRow[u].Weights);
909+
u--;
910+
}
911+
return NULL;
912+
}
913+
}
914+
return res;
896915
}
897916

898917
static inline void _gdContributionsFree(LineContribType * p)
@@ -907,59 +926,62 @@ static inline void _gdContributionsFree(LineContribType * p)
907926

908927
static inline LineContribType *_gdContributionsCalc(unsigned int line_size, unsigned int src_size, double scale_d, const interpolation_method pFilter)
909928
{
910-
double width_d;
911-
double scale_f_d = 1.0;
912-
const double filter_width_d = DEFAULT_BOX_RADIUS;
929+
double width_d;
930+
double scale_f_d = 1.0;
931+
const double filter_width_d = DEFAULT_BOX_RADIUS;
913932
int windows_size;
914933
unsigned int u;
915934
LineContribType *res;
935+
int overflow_error = 0;
916936

917-
if (scale_d < 1.0) {
918-
width_d = filter_width_d / scale_d;
919-
scale_f_d = scale_d;
920-
} else {
921-
width_d= filter_width_d;
922-
}
923-
924-
windows_size = 2 * (int)ceil(width_d) + 1;
925-
res = _gdContributionsAlloc(line_size, windows_size);
937+
if (scale_d < 1.0) {
938+
width_d = filter_width_d / scale_d;
939+
scale_f_d = scale_d;
940+
} else {
941+
width_d= filter_width_d;
942+
}
926943

927-
for (u = 0; u < line_size; u++) {
928-
const double dCenter = (double)u / scale_d;
929-
/* get the significant edge points affecting the pixel */
930-
register int iLeft = MAX(0, (int)floor (dCenter - width_d));
931-
int iRight = MIN((int)ceil(dCenter + width_d), (int)src_size - 1);
932-
double dTotalWeight = 0.0;
944+
windows_size = 2 * (int)ceil(width_d) + 1;
945+
res = _gdContributionsAlloc(line_size, windows_size);
946+
if (res == NULL) {
947+
return NULL;
948+
}
949+
for (u = 0; u < line_size; u++) {
950+
const double dCenter = (double)u / scale_d;
951+
/* get the significant edge points affecting the pixel */
952+
register int iLeft = MAX(0, (int)floor (dCenter - width_d));
953+
int iRight = MIN((int)ceil(dCenter + width_d), (int)src_size - 1);
954+
double dTotalWeight = 0.0;
933955
int iSrc;
934956

935-
/* Cut edge points to fit in filter window in case of spill-off */
936-
if (iRight - iLeft + 1 > windows_size) {
937-
if (iLeft < ((int)src_size - 1 / 2)) {
938-
iLeft++;
939-
} else {
940-
iRight--;
941-
}
942-
}
957+
/* Cut edge points to fit in filter window in case of spill-off */
958+
if (iRight - iLeft + 1 > windows_size) {
959+
if (iLeft < ((int)src_size - 1 / 2)) {
960+
iLeft++;
961+
} else {
962+
iRight--;
963+
}
964+
}
943965

944-
res->ContribRow[u].Left = iLeft;
945-
res->ContribRow[u].Right = iRight;
966+
res->ContribRow[u].Left = iLeft;
967+
res->ContribRow[u].Right = iRight;
946968

947-
for (iSrc = iLeft; iSrc <= iRight; iSrc++) {
948-
dTotalWeight += (res->ContribRow[u].Weights[iSrc-iLeft] = scale_f_d * (*pFilter)(scale_f_d * (dCenter - (double)iSrc)));
949-
}
969+
for (iSrc = iLeft; iSrc <= iRight; iSrc++) {
970+
dTotalWeight += (res->ContribRow[u].Weights[iSrc-iLeft] = scale_f_d * (*pFilter)(scale_f_d * (dCenter - (double)iSrc)));
971+
}
950972

951973
if (dTotalWeight < 0.0) {
952974
_gdContributionsFree(res);
953975
return NULL;
954976
}
955977

956-
if (dTotalWeight > 0.0) {
957-
for (iSrc = iLeft; iSrc <= iRight; iSrc++) {
958-
res->ContribRow[u].Weights[iSrc-iLeft] /= dTotalWeight;
959-
}
960-
}
961-
}
962-
return res;
978+
if (dTotalWeight > 0.0) {
979+
for (iSrc = iLeft; iSrc <= iRight; iSrc++) {
980+
res->ContribRow[u].Weights[iSrc-iLeft] /= dTotalWeight;
981+
}
982+
}
983+
}
984+
return res;
963985
}
964986

965987
static inline void _gdScaleRow(gdImagePtr pSrc, unsigned int src_width, gdImagePtr dst, unsigned int dst_width, unsigned int row, LineContribType *contrib)

ext/gd/tests/bug72512_0.phpt

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
--TEST--
2+
Bug #72512 gdImageTrueColorToPaletteBody allows arbitrary write/read access, var 0
3+
--SKIPIF--
4+
<?php
5+
if (!extension_loaded('gd')) die("skip gd extension not available\n");
6+
?>
7+
--FILE--
8+
<?php
9+
10+
$img = imagecreatetruecolor(13, 1007);
11+
12+
imagecolortransparent($img, -10066304);
13+
imagetruecolortopalette($img, TRUE, 3);
14+
imagescale($img, 1, 65535);
15+
?>
16+
==DONE==
17+
--EXPECT--
18+
==DONE==

0 commit comments

Comments
 (0)