Fix a buffer overflow in PHP's built-in wordwrap() function.
If you use the wordwrap() function on user-supplied input, a specially-crafted input can overflow the allocated buffer and overwrite the heap. Exploit looks very difficult, but still theoretically possible. http://marc.theaimsgroup.com/?l=bugtraq&m=104102689503192 http://bugs.php.net/bug.php?id=20927
This commit is contained in:
parent
770d499273
commit
1e3e008f8e
@ -1,7 +1,7 @@
|
||||
# $OpenBSD: Makefile,v 1.6 2002/09/11 23:16:48 avsm Exp $
|
||||
# $OpenBSD: Makefile,v 1.7 2003/02/06 05:28:49 brad Exp $
|
||||
|
||||
COMMENT= "server-side HTML-embedded scripting language"
|
||||
PKGNAME= php4-core-${V}
|
||||
PKGNAME= php4-core-${V}p1
|
||||
|
||||
CONFIGURE_ARGS+= --with-apxs=/usr/sbin/apxs \
|
||||
--without-mysql \
|
||||
|
106
www/php4/core/patches/patch-ext_standard_string_c
Normal file
106
www/php4/core/patches/patch-ext_standard_string_c
Normal file
@ -0,0 +1,106 @@
|
||||
$OpenBSD: patch-ext_standard_string_c,v 1.1 2003/02/06 05:28:49 brad Exp $
|
||||
--- ext/standard/string.c.orig Mon Jun 24 04:19:43 2002
|
||||
+++ ext/standard/string.c Wed Feb 5 23:54:56 2003
|
||||
@@ -616,7 +616,7 @@ PHP_FUNCTION(wordwrap)
|
||||
{
|
||||
const char *text, *breakchar = "\n";
|
||||
char *newtext;
|
||||
- int textlen, breakcharlen = 1, newtextlen;
|
||||
+ int textlen, breakcharlen = 1, newtextlen, alloced, chk;
|
||||
long current = 0, laststart = 0, lastspace = 0;
|
||||
long linelength = 75;
|
||||
zend_bool docut = 0;
|
||||
@@ -642,38 +642,40 @@ PHP_FUNCTION(wordwrap)
|
||||
for (current = 0; current < textlen; current++) {
|
||||
if (text[current] == breakchar[0]) {
|
||||
laststart = lastspace = current;
|
||||
- }
|
||||
- else if (text[current] == ' ') {
|
||||
+ } else if (text[current] == ' ') {
|
||||
if (current - laststart >= linelength) {
|
||||
newtext[current] = breakchar[0];
|
||||
laststart = current;
|
||||
}
|
||||
lastspace = current;
|
||||
- }
|
||||
- else if (current - laststart >= linelength
|
||||
- && laststart != lastspace) {
|
||||
+ } else if (current - laststart >= linelength && laststart != lastspace) {
|
||||
newtext[lastspace] = breakchar[0];
|
||||
laststart = lastspace;
|
||||
}
|
||||
}
|
||||
|
||||
RETURN_STRINGL(newtext, textlen, 0);
|
||||
- }
|
||||
- else {
|
||||
+ } else {
|
||||
/* Multiple character line break or forced cut */
|
||||
if (linelength > 0) {
|
||||
- newtextlen = textlen + (textlen/linelength + 1) * breakcharlen + 1;
|
||||
- }
|
||||
- else {
|
||||
- newtextlen = textlen * (breakcharlen + 1) + 1;
|
||||
+ chk = (int)(textlen/linelength + 1);
|
||||
+ alloced = textlen + chk * breakcharlen + 1;
|
||||
+ } else {
|
||||
+ chk = textlen;
|
||||
+ alloced = textlen * (breakcharlen + 1) + 1;
|
||||
}
|
||||
- newtext = emalloc(newtextlen);
|
||||
+ newtext = emalloc(alloced);
|
||||
|
||||
/* now keep track of the actual new text length */
|
||||
newtextlen = 0;
|
||||
|
||||
laststart = lastspace = 0;
|
||||
for (current = 0; current < textlen; current++) {
|
||||
+ if (chk <= 0) {
|
||||
+ alloced += (int) (((textlen - current + 1)/linelength + 1) * breakcharlen) + 1;
|
||||
+ newtext = erealloc(newtext, alloced);
|
||||
+ chk = (int) ((textlen - current)/linelength) + 1;
|
||||
+ }
|
||||
/* when we hit an existing break, copy to new buffer, and
|
||||
* fix up laststart and lastspace */
|
||||
if (text[current] == breakchar[0]
|
||||
@@ -683,6 +685,7 @@ PHP_FUNCTION(wordwrap)
|
||||
newtextlen += current-laststart+breakcharlen;
|
||||
current += breakcharlen - 1;
|
||||
laststart = lastspace = current + 1;
|
||||
+ chk--;
|
||||
}
|
||||
/* if it is a space, check if it is at the line boundary,
|
||||
* copy and insert a break, or just keep track of it */
|
||||
@@ -693,6 +696,7 @@ PHP_FUNCTION(wordwrap)
|
||||
memcpy(newtext+newtextlen, breakchar, breakcharlen);
|
||||
newtextlen += breakcharlen;
|
||||
laststart = current + 1;
|
||||
+ chk--;
|
||||
}
|
||||
lastspace = current;
|
||||
}
|
||||
@@ -706,6 +710,7 @@ PHP_FUNCTION(wordwrap)
|
||||
memcpy(newtext+newtextlen, breakchar, breakcharlen);
|
||||
newtextlen += breakcharlen;
|
||||
laststart = lastspace = current;
|
||||
+ chk--;
|
||||
}
|
||||
/* if the current word puts us over the linelength, copy
|
||||
* back up until the last space, insert a break, and move
|
||||
@@ -717,6 +722,7 @@ PHP_FUNCTION(wordwrap)
|
||||
memcpy(newtext+newtextlen, breakchar, breakcharlen);
|
||||
newtextlen += breakcharlen;
|
||||
laststart = lastspace = lastspace + 1;
|
||||
+ chk--;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -727,6 +733,8 @@ PHP_FUNCTION(wordwrap)
|
||||
}
|
||||
|
||||
newtext[newtextlen] = '\0';
|
||||
+ /* free unused memory */
|
||||
+ newtext = erealloc(newtext, newtextlen+1);
|
||||
|
||||
RETURN_STRINGL(newtext, newtextlen, 0);
|
||||
}
|
Loading…
Reference in New Issue
Block a user