Bug #62852 [Com]: Unserialize Invalid Date causes crash

From: Date: Fri, 07 Mar 2014 23:48:43 +0000
Subject: Bug #62852 [Com]: Unserialize Invalid Date causes crash
References: 1  Groups: php.bugs 
Request: Send a blank email to php-bugs+get-184614@lists.php.net to get a copy of this message
Edit report at https://bugs.php.net/bug.php?id=62852&edit=1

 ID:                 62852
 Comment by:         Matthew dot J dot Mucklo at qvc dot com
 Reported by:        kasper at webmasteren dot eu
 Summary:            Unserialize Invalid Date causes crash
 Status:             Closed
 Type:               Bug
 Package:            Reproducible crash
 Operating System:   windows, linux
 PHP Version:        Irrelevant
 Assigned To:        laruence
 Block user comment: N
 Private report:     N

 New Comment:

We've been seeing the same thing in production.

It's been tough to trace down exactly how to reproduce it, so we ended up patching
php_memcached.c so that these sorts of things don't get saved into memcache (we also had to do
a similar filter for session saving as the serialization happens in a different place):

Diff is below:


--- php_memcached.c	2014-02-05 16:00:37.000000000 -0800
+++ memcached_master_02_05_2014/php_memcached.c	2014-02-06 11:01:27.000000000 -0800
@@ -3193,6 +3193,44 @@
 				php_error_docref(NULL TSRMLS_CC, E_WARNING, "could not serialize value");
 				return 0;
 			}
+
+            const char * const cmp = "\"DateTime\":0:{}";
+            const size_t cmplen = 15;
+            if (buf->len >= cmplen)
+            {
+                size_t len = buf->len - cmplen;
+                char *c = buf->c;
+                size_t i = 0;
+                while(i <= len)
+                {
+                    if (*c == *cmp) {
+                        char *cmp1 = cmp + 1;
+
+                        // Run the comparison
+                        while (*cmp1) {
+                            c++;
+                            i++;
+                            if (*c != *cmp1)
+                            {
+                                break;
+                            }
+                            cmp1++;
+                        }
+
+                        // match
+                        if (!*cmp1)
+                        {
+                            php_error_docref(NULL TSRMLS_CC, E_WARNING, "could not serialize
DateTime value");
+                            return 0;
+                        }
+                    }
+                    else
+                    {
+                        c++;
+                        i++;
+                    }
+                }
+            }
 			MEMC_VAL_SET_TYPE(*flags, MEMC_VAL_IS_SERIALIZED);
 		}
 			break;


Previous Comments:
------------------------------------------------------------------------
[2014-01-23 12:13:18] mail at ericreiche dot net

Forgot to mention, version is 5.4.21-1~dotdeb.1

------------------------------------------------------------------------
[2014-01-23 12:12:38] mail at ericreiche dot net

I'm also still getting this with empty DateTime object in session data
O:8:"DateTime":0:{}.

------------------------------------------------------------------------
[2013-11-17 09:31:39] laruence@php.net

Automatic comment on behalf of ab
Revision: http://git.php.net/?p=php-src.git;a=commit;h=f8b91d9acff10ede7bd3f2bc631794a3abef8ff7
Log: Fixed bug #62852 Unserialize Invalid Date crash

------------------------------------------------------------------------
[2013-11-05 02:59:59] mkwan at corp dot oodle dot com

According to the documentation, if "the passed string is not unserializeable, FALSE is returned
and E_NOTICE is issued."
http://php.net/manual/en/function.unserialize.php

Why is it that if the string happens to looks like a DateTime, instead an unrecoverable E_ERROR is
issued?

------------------------------------------------------------------------
[2013-04-19 20:42:52] webmaster at thedigitalorchard dot ca

My [ugly] workaround for this problem is to manually replace instances of 
serialized DateTime objects with a fake, non-existent class name, which avoids 
this crash.

$str = 'O:8:"DateTime":0:{}';
$str = str_replace('O:8:"DateTime"', 'O:12:"PHP_DateTime"',
$str);

Of course, if the serialized data needed to be recovered, an alternate approach 
would be needed. In my own case, I want to be discarding this object. I'm hoping 
this issue that ran into is an unforeseen issue with this latest bug fix, and a 
proper fix can be made in a future update. I don't like adding in workarounds. :-)

------------------------------------------------------------------------


The remainder of the comments for this report are too long. To view
the rest of the comments, please view the bug report online at

    https://bugs.php.net/bug.php?id=62852


-- 
Edit this bug report at https://bugs.php.net/bug.php?id=62852&edit=1


Thread (26 messages)

« previous php.bugs (#184614) next »