php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Doc Bug #35060 problematic safe_mode restriction in GD library
Submitted: 2005-11-01 22:11 UTC Modified: 2005-11-02 22:29 UTC
Votes:13
Avg. Score:4.8 ± 0.6
Reproduced:11 of 12 (91.7%)
Same Version:10 (90.9%)
Same OS:5 (45.5%)
From: moron at industrial dot org Assigned:
Status: Not a bug Package: Documentation problem
PHP Version: 4.4.1RC1 OS: FreeBSD (likely all)
Private report: No CVE-ID:
 [2005-11-01 22:11 UTC] moron at industrial dot org
Description:
------------
A new safe_mode check has been added to PHP's GD library functions that affects image creation functions.  The changed line is here:

ext/gd/gd.c:1647: if (!fn || fn == empty_string || php_check_open_basedir(fn TSRMLS_CC) || (PG(safe_mode) && !php_checkuid(fn, "rb+", CHECKUID_CHECK_FILE_AND_DIR))) {

As of 4.4.1 the following is new:

(PG(safe_mode) && !php_checkuid(fn, "rb+", CHECKUID_CHECK_FILE_AND_DIR))

Since this change GD is not able to create new images, presumably due to the above permissions check failing.


The problem with this code (if I am guessing what "php_checkuid" does correctly) is that it seems to make an invalid assumption as to how ownership works under Unix operating systems. Unless you run PHP as a CGI (running as the script owner), created files will always be owned by the generic web user ("www", "nobody", etc.).  This means that the above check will fail since the ownership of the created file will not match that of the parent script.

What should be checked here is the group ownership and file level permissions since the owner will always be the web user (especially if the directory structure has been created on the fly). 

As it stands, if you run under safe_mode and with PHP as a module under a Unix type system, you will always fail the safe_mode check and be unable to create images with the GD libraries.

Other file system functions appear to be unaffected (i.e. move_uploaded_file, copy, mkdir, etc.).

Cheers

Reproduce code:
---------------
<?php
// safe_mode is enabled

$img_out=imagecreatetruecolor(200,200);
imagejpeg($img_out,'files/thingy/test.jpg',100);
imagedestroy($img_out);
?>
                



Expected result:
----------------
new image created "files/thingy/test.jpg"

Actual result:
--------------
Warning: imagejpeg(): Unable to access files/thingy/test.jpg in /home/moron/www/test.php on line 3

Warning: imagejpeg(): Invalid filename 'files/thingy/test.jpg' in /home/moron/www/test.php on line 3

Here are the permissions in that directory:

drwxr-xrwx  15 nobody  12345  512 Sep 10  2004 files/thingy/

Here are the permissions on the script:

-rw-r--r--  1 33300  12345    122 Nov  1 13:03 test.php

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2005-11-01 22:39 UTC] jerome at blion dot dyndns dot org
touch('files/thingy/test.jpg');
before imagejpeg worked for me
 [2005-11-01 22:51 UTC] sniper@php.net
and in PHP 5.1 there are even MORE of these checks! =)
(hint: this is not a bug but a feature)


 [2005-11-01 22:57 UTC] moron at industrial dot org
What is bogus about the bug exactly? If "touch()" can create the file then so should imagejpeg() - is that not the entire point of that function, to create a file?  Nothing in the docus that I could see state that the file needs to exist previously. 

Also, if this is a "feature" can you please explain what that feature is exactly?  It does not seem to adhere to any sane permission scheme I can think of, at least as far as running PHP as a module under UNIX style operating systems go.

If this "feature" will not be going away, any chance of getting the imagejpeg docs updated to note that the new requirement is that the file in question already exists before it can be written to?

Cheers
 [2005-11-01 23:00 UTC] moron at industrial dot org
http://ca.php.net/manual/en/function.imagejpeg.php

"imagejpeg() creates the JPEG file in filename from the image image. The image argument is the return from the imagecreatetruecolor() function."

This definition conflicts with the newly stated requirement that the file in question already exists.  Either the docs are wrong or the safe_mode check is broken.
 [2005-11-02 14:19 UTC] sniper@php.net
Docs are wrong.
 [2005-11-02 17:53 UTC] moron at industrial dot org
Ok.  As an aside though, they have been "wrong" for at least two or three years now and I have been using the stated functionality in both PHP 4 and 5 successfully for quite a while so changing this behaviour will affect any application that uses the GD functions under "safe_mode".  

It's also a bit illogical to have to create the file first, no?  

Again, if "touch" and "copy" and "move_uploaded_file" and "unlink" all can have access to the file in question (as they should in this scenario), why can't "imagejpeg" do the same "safe_mode" access checks (as it seems to be attempting to do when looking at the source)?  The file it wants to create is within the open_basedir limits, it is under a directory with world write permissions and it is owned by the same group as the script running.

Cheers
 [2005-11-02 19:37 UTC] neverloop at gmail dot com
Changing the way functions work within a minor update (version+=0.0.1) is an irresponsible way of maintaining software. This bug (please don't call it a "feature") caused a lot of trouble on our servers.
 [2005-11-02 21:48 UTC] no at email dot com
See also http://bugs.php.net/bug.php?id=35071

Same issue, but suggestion for bugfix provided by author there.
 [2005-11-02 22:29 UTC] sniper@php.net
Bogusing this in favor of the much better bug #35071 report.

 [2012-12-23 07:25 UTC] skewl at gmail dot com
t to open ahmadinejad toastmasters, but to open ahmadinejad exhibition - this is his mother university.http://www.mbtukshop.co.uk/
 
PHP Copyright © 2001-2014 The PHP Group
All rights reserved.
Last updated: Wed Apr 23 14:02:33 2014 UTC