How I found an integer overflow in PHP-FPM
This week I solved a stange problem I had with my personel ownCloud instance. When uploading a file I always got an error that the uploaded file was larger than MAX_FILE_UPLOAD.
After some digging in the ownCloud PHP code I tracked this down to an error 2 ( UPLOAD_ERR_FORM_SIZE) in the PHP built-in array $_FILES used for file uploads. This indicates that the uploaded file was larger than MAX_FILE_UPLOAD.
At this point I was stuck to a while. I looked for a solution and only found people with low values for upload_max_filesize in their php.ini. This was definitely not the issue in my case as this value was set to 8G in my php.ini.
Finally a friend of mine brought up an idea I had once but didn’t investigate: What if the MAX_FILE_SIZE is not to small but to large. Meaning there is an overflow somewhere. Dividing that value by about 1000 in a test form I wrote showed it was a good trail. Suddenly I could upload files.
After some binary search I had the largest value for MAX_FILE_SIZE that worked: 2147483647 (2^31-1). This looks a lot like an integer overflow of a signed int. Using my test form and my test php script on a different machine (CentOS with an Apache2 and mod-php) didn’t show that error so I assume it’s a bug in the implementation of php-fpm.
Setting upload_max_filesize to 2000M (2G is just to large) fixed the problem and I can upload files to my server now. As a final action I filed a bug in the bug tracker of php and now I’m waiting for it to be fixed.
Update: The bug report can be found here