File php-5.1.4-security-fix-3.patch of Package php
--- php-5.1.2/ext/curl/interface.c
+++ php-5.1.2/ext/curl/interface.c
@@ -119,6 +119,11 @@
RETURN_FALSE; \
} \
\
+ if (php_memnstr(str, tmp_url->path, strlen(tmp_url->path), str + len)) { \
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Url '%s' contains unencoded control characters.", str); \
+ RETURN_FALSE; \
+ } \
+ \
if (tmp_url->query || tmp_url->fragment || php_check_open_basedir(tmp_url->path TSRMLS_CC) || \
(PG(safe_mode) && !php_checkuid(tmp_url->path, "rb+", CHECKUID_CHECK_MODE_PARAM)) \
) { \
@@ -979,7 +984,6 @@
case CURLOPT_FTPLISTONLY:
case CURLOPT_FTPAPPEND:
case CURLOPT_NETRC:
- case CURLOPT_FOLLOWLOCATION:
case CURLOPT_PUT:
#if CURLOPT_MUTE != 0
case CURLOPT_MUTE:
@@ -1030,6 +1034,16 @@
convert_to_long_ex(zvalue);
error = curl_easy_setopt(ch->cp, option, Z_LVAL_PP(zvalue));
break;
+ case CURLOPT_FOLLOWLOCATION:
+ convert_to_long_ex(zvalue);
+ if ((PG(open_basedir) && *PG(open_basedir)) || PG(safe_mode)) {
+ if (Z_LVAL_PP(zvalue) != 0) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "CURLOPT_FOLLOWLOCATION cannot be activated when in safe_mode or an open_basedir is set");
+ RETURN_FALSE;
+ }
+ }
+ error = curl_easy_setopt(ch->cp, option, Z_LVAL_PP(zvalue));
+ break;
case CURLOPT_URL:
case CURLOPT_PROXY:
case CURLOPT_USERPWD:
--- php-5.1.2/ext/curl/streams.c
+++ php-5.1.2/ext/curl/streams.c
@@ -289,7 +289,11 @@
curl_easy_setopt(curlstream->curl, CURLOPT_WRITEHEADER, stream);
/* currently buggy (bug is in curl) */
- curl_easy_setopt(curlstream->curl, CURLOPT_FOLLOWLOCATION, 1);
+ if ((PG(open_basedir) && *PG(open_basedir)) || PG(safe_mode)) {
+ curl_easy_setopt(curlstream->curl, CURLOPT_FOLLOWLOCATION, 0);
+ } else {
+ curl_easy_setopt(curlstream->curl, CURLOPT_FOLLOWLOCATION, 1);
+ }
curl_easy_setopt(curlstream->curl, CURLOPT_ERRORBUFFER, curlstream->errstr);
curl_easy_setopt(curlstream->curl, CURLOPT_VERBOSE, 0);
--- php-5.1.2/ext/standard/basic_functions.c
+++ php-5.1.2/ext/standard/basic_functions.c
@@ -2024,7 +2024,7 @@
break;
case 3: /*save to a file */
- stream = php_stream_open_wrapper(opt, "a", IGNORE_URL | ENFORCE_SAFE_MODE | REPORT_ERRORS, NULL);
+ stream = php_stream_open_wrapper(opt, "a", IGNORE_URL_WIN | ENFORCE_SAFE_MODE | REPORT_ERRORS, NULL);
if (!stream)
return FAILURE;
php_stream_write(stream, message, strlen(message));
--- php-5.1.2/ext/standard/string.c
+++ php-5.1.2/ext/standard/string.c
@@ -632,7 +632,8 @@
{
const char *text, *breakchar = "\n";
char *newtext;
- int textlen, breakcharlen = 1, newtextlen, alloced, chk;
+ int textlen, breakcharlen = 1, newtextlen, chk;
+ size_t alloced;
long current = 0, laststart = 0, lastspace = 0;
long linelength = 75;
zend_bool docut = 0;
@@ -4194,7 +4195,7 @@
zval **input_str; /* Input string */
zval **mult; /* Multiplier */
char *result; /* Resulting string */
- int result_len; /* Length of the resulting string */
+ size_t result_len; /* Length of the resulting string */
if (ZEND_NUM_ARGS() != 2 || zend_get_parameters_ex(2, &input_str, &mult) == FAILURE) {
WRONG_PARAM_COUNT;
@@ -4219,11 +4220,7 @@
/* Initialize the result string */
result_len = Z_STRLEN_PP(input_str) * Z_LVAL_PP(mult);
- if (result_len < 1 || result_len > 2147483647) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "You may not create strings longer than 2147483647 bytes");
- RETURN_FALSE;
- }
- result = (char *)emalloc(result_len + 1);
+ result = (char *)safe_emalloc(Z_STRLEN_PP(input_str), Z_LVAL_PP(mult), 1);
/* Heavy optimization for situations where input string is 1 byte long */
if (Z_STRLEN_PP(input_str) == 1) {
--- php-5.1.2/main/main.c
+++ php-5.1.2/main/main.c
@@ -1091,6 +1091,11 @@
sapi_add_header(SAPI_PHP_VERSION_HEADER, sizeof(SAPI_PHP_VERSION_HEADER)-1, 1);
}
+ /* Disable realpath cache if safe_mode or open_basedir are set */
+ if (PG(safe_mode) || (PG(open_basedir) && *PG(open_basedir))) {
+ CWDG(realpath_cache_size_limit) = 0;
+ }
+
if (PG(output_handler) && PG(output_handler)[0]) {
php_start_ob_buffer_named(PG(output_handler), 0, 1 TSRMLS_CC);
} else if (PG(output_buffering)) {
--- php-5.1.2/Zend/zend_alloc.c
+++ php-5.1.2/Zend/zend_alloc.c
@@ -72,7 +72,15 @@
#define CHECK_MEMORY_LIMIT(s, rs) _CHECK_MEMORY_LIMIT(s, rs, NULL, 0)
# endif
-#define _CHECK_MEMORY_LIMIT(s, rs, file, lineno) { AG(allocated_memory) += rs;\
+#define _CHECK_MEMORY_LIMIT(s, rs, file, lineno) { if ((ssize_t)(rs) > (ssize_t)(INT_MAX - AG(allocated_memory))) { \
+ if (file) { \
+ fprintf(stderr, "Integer overflow in memory_limit check detected at %s:%d\n", file, lineno); \
+ } else { \
+ fprintf(stderr, "Integer overflow in memory_limit check detected\n"); \
+ } \
+ exit(1); \
+ } \
+ AG(allocated_memory) += rs;\
if (AG(memory_limit)<AG(allocated_memory)) {\
int php_mem_limit = AG(memory_limit); \
AG(allocated_memory) -= rs; \
@@ -142,11 +150,15 @@
ZEND_API void *_emalloc(size_t size ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC)
{
- zend_mem_header *p;
+ zend_mem_header *p = NULL;
DECLARE_CACHE_VARS();
TSRMLS_FETCH();
CALCULATE_REAL_SIZE_AND_CACHE_INDEX(size);
+
+ if (size > INT_MAX || SIZE < size) {
+ goto emalloc_error;
+ }
#if !ZEND_DISABLE_MEMORY_CACHE
if ((CACHE_INDEX < MAX_CACHED_MEMORY) && (AG(cache_count)[CACHE_INDEX] > 0)) {
@@ -184,6 +196,8 @@
}
#endif
+emalloc_error:
+
HANDLE_BLOCK_INTERRUPTIONS();
if (!p) {
@@ -357,6 +371,13 @@
CALCULATE_REAL_SIZE_AND_CACHE_INDEX(size);
HANDLE_BLOCK_INTERRUPTIONS();
+
+ if (size > INT_MAX || SIZE < size) {
+ REMOVE_POINTER_FROM_LIST(p);
+ p = NULL;
+ goto erealloc_error;
+ }
+
#if MEMORY_LIMIT
CHECK_MEMORY_LIMIT(size - p->size, SIZE - REAL_SIZE(p->size));
if (AG(allocated_memory) > AG(allocated_memory_peak)) {
@@ -365,6 +386,7 @@
#endif
REMOVE_POINTER_FROM_LIST(p);
p = (zend_mem_header *) ZEND_DO_REALLOC(p, sizeof(zend_mem_header)+MEM_HEADER_PADDING+SIZE+END_MAGIC_SIZE);
+erealloc_error:
if (!p) {
if (!allow_failure) {
fprintf(stderr,"FATAL: erealloc(): Unable to allocate %ld bytes\n", (long) size);
--- php-5.1.2/ext/wddx/wddx.c 2006/04/23 16:02:05 1.119.2.10
+++ php-5.1.2/ext/wddx/wddx.c 2006/08/02 22:03:47 1.119.2.10.2.6
@@ -366,53 +366,22 @@
/* {{{ php_wddx_serialize_string
*/
-static void php_wddx_serialize_string(wddx_packet *packet, zval *var)
+static void php_wddx_serialize_string(wddx_packet *packet, zval *var TSRMLS_DC)
{
- char *buf,
- *p,
- *vend,
- control_buf[WDDX_BUF_LEN];
- int l;
-
php_wddx_add_chunk_static(packet, WDDX_STRING_S);
if (Z_STRLEN_P(var) > 0) {
- l = 0;
- vend = Z_STRVAL_P(var) + Z_STRLEN_P(var);
- buf = (char *)emalloc(Z_STRLEN_P(var) + 1);
-
- for(p = Z_STRVAL_P(var); p != vend; p++) {
- switch (*p) {
- case '<':
- FLUSH_BUF();
- php_wddx_add_chunk_static(packet, "<");
- break;
-
- case '&':
- FLUSH_BUF();
- php_wddx_add_chunk_static(packet, "&");
- break;
-
- case '>':
- FLUSH_BUF();
- php_wddx_add_chunk_static(packet, ">");
- break;
-
- default:
- if (iscntrl((int)*(unsigned char *)p)) {
- FLUSH_BUF();
- sprintf(control_buf, WDDX_CHAR, *p);
- php_wddx_add_chunk(packet, control_buf);
- } else
- buf[l++] = *p;
- break;
- }
- }
+ char *buf, *enc;
+ int buf_len, enc_len;
+
+ buf = php_escape_html_entities(Z_STRVAL_P(var), Z_STRLEN_P(var), &buf_len, 0, ENT_QUOTES, NULL TSRMLS_CC);
+ enc = xml_utf8_encode(buf, buf_len, &enc_len, "ISO-8859-1");
+
+ php_wddx_add_chunk_ex(packet, enc, enc_len);
- FLUSH_BUF();
efree(buf);
+ efree(enc);
}
-
php_wddx_add_chunk_static(packet, WDDX_STRING_E);
}
/* }}} */
@@ -638,7 +607,7 @@
switch(Z_TYPE_P(var)) {
case IS_STRING:
- php_wddx_serialize_string(packet, var);
+ php_wddx_serialize_string(packet, var TSRMLS_CC);
break;
case IS_LONG:
@@ -723,7 +692,7 @@
if (!strcmp(name, EL_PACKET)) {
int i;
- for (i=0; atts[i]; i++) {
+ if (atts) for (i=0; atts[i]; i++) {
if (!strcmp(atts[i], EL_VERSION)) {
/* nothing for now */
}
@@ -751,7 +720,7 @@
} else if (!strcmp(name, EL_CHAR)) {
int i;
- for (i = 0; atts[i]; i++) {
+ if (atts) for (i = 0; atts[i]; i++) {
if (!strcmp(atts[i], EL_CHAR_CODE) && atts[++i] && atts[i][0]) {
char tmp_buf[2];
@@ -771,7 +740,7 @@
} else if (!strcmp(name, EL_BOOLEAN)) {
int i;
- for (i = 0; atts[i]; i++) {
+ if (atts) for (i = 0; atts[i]; i++) {
if (!strcmp(atts[i], EL_VALUE) && atts[++i] && atts[i][0]) {
ent.type = ST_BOOLEAN;
SET_STACK_VARNAME;
@@ -812,7 +781,7 @@
} else if (!strcmp(name, EL_VAR)) {
int i;
- for (i = 0; atts[i]; i++) {
+ if (atts) for (i = 0; atts[i]; i++) {
if (!strcmp(atts[i], EL_NAME) && atts[++i] && atts[i][0]) {
char *decoded;
int decoded_len;
@@ -829,7 +798,7 @@
MAKE_STD_ZVAL(ent.data);
array_init(ent.data);
- for (i = 0; atts[i]; i++) {
+ if (atts) for (i = 0; atts[i]; i++) {
if (!strcmp(atts[i], "fieldNames") && atts[++i] && atts[i][0]) {
zval *tmp;
char *key;
@@ -869,7 +838,7 @@
ent.varname = NULL;
ent.data = NULL;
- for (i = 0; atts[i]; i++) {
+ if (atts) for (i = 0; atts[i]; i++) {
if (!strcmp(atts[i], EL_NAME) && atts[++i] && atts[i][0]) {
char *decoded;
int decoded_len;
--- php-5.1.2/ext/xml/xml.c 2006/06/15 18:33:09 1.157.2.4.2.1
+++ php-5.1.2/ext/xml/xml.c 2006/08/02 15:21:54 1.157.2.4.2.2
@@ -79,7 +79,6 @@
inline static char xml_decode_iso_8859_1(unsigned short);
inline static unsigned short xml_encode_us_ascii(unsigned char);
inline static char xml_decode_us_ascii(unsigned short);
-static XML_Char *xml_utf8_encode(const char *, int, int *, const XML_Char *);
static zval *xml_call_handler(xml_parser *, zval *, zend_function *, int, zval **);
static zval *_xml_xmlchar_zval(const XML_Char *, int, const XML_Char *);
static int _xml_xmlcharlen(const XML_Char *);
@@ -497,7 +496,7 @@
/* }}} */
/* {{{ xml_utf8_encode */
-static XML_Char *xml_utf8_encode(const char *s, int len, int *newlen, const XML_Char *encoding)
+PHPAPI char *xml_utf8_encode(const char *s, int len, int *newlen, const XML_Char *encoding)
{
int pos = len;
char *newbuf;
--- php-5.1.2/ext/xml/php_xml.h 2006/06/15 18:33:09 1.28.2.2.2.1
+++ php-5.1.2/ext/xml/php_xml.h 2006/08/02 15:21:54 1.28.2.2.2.2
@@ -141,6 +141,7 @@
PHPAPI char *_xml_zval_strdup(zval *val);
PHPAPI char *xml_utf8_decode(const XML_Char *, int, int *, const XML_Char *);
+PHPAPI char *xml_utf8_encode(const char *s, int len, int *newlen, const XML_Char *encoding);
#endif /* HAVE_LIBEXPAT */