Знайшов баг в wordpress (Ticket #8428)

errorВ понеділок вручну переносив блог з одного сервака на інший – все ніби нормально запустилось. Та коли сьогодні хотів зааплоадити картинку в галерею, то отримав:

502 Bad Gateway
nginx/0.5.32


Я спочатку подумав, що то знову nginx вимахується (на старому сервері його не було). Написав в support. Вони звернули мою увагу, на error лог апача:

[Sat Nov 29 16:49:32 2008] [error] [client 89.188.112.189] PHP Warning: file_exists() [function.file-exists]: open_basedir restriction in effect. File(/) is not within the allowed path(s): (/home/stfalcon/data:.) in /home/stfalcon/data/www/blog.stfalcon.com/wp-includes/functions.php on line 1435, referer: http://tanasiychuk.com/wp-admin/media-upload.php?post_id=-1227969082&type=image&flash=0
[Sat Nov 29 16:49:32 2008] [error] [client 89.188.112.189] PHP Warning: is_dir() [function.is-dir]: open_basedir restriction in effect. File(/) is not within the allowed path(s): (/home/stfalcon/data:.) in /home/stfalcon/data/www/blog.stfalcon.com/wp-includes/functions.php on line 1444, referer: http://tanasiychuk.com/wp-admin/media-upload.php?post_id=-1227969082&type=image&flash=0

І сказали, що проблема швидш за все в open_basedir.

Глянув на open_basedir в httpd.conf. Шлях прописаний нормальний – блогу мало його вистачати з головою.

Втикнув на логи. Помилка виникала в функції wp_mkdir_p:

function wp_mkdir_p( $target ) {
	// from php.net/mkdir user contributed notes
	$target = str_replace( '//', '/', $target );
	if ( file_exists( $target ) )
		return @is_dir( $target );
 
	// Attempting to create the directory may clutter up our display.
	if ( @mkdir( $target ) ) {
		$stat = @stat( dirname( $target ) );
		$dir_perms = $stat['mode'] & 0007777;  // Get the permission bits.
		@chmod( $target, $dir_perms );
		return true;
	} elseif ( is_dir( dirname( $target ) ) ) {
			return false;
	}
 
	// If the above failed, attempt to create the parent node, then try again.
	if ( wp_mkdir_p( dirname( $target ) ) )
		return wp_mkdir_p( $target );
 
	return false;
}

Судячи з error логу вона ломилась в корінь сервака, а сам лог був метрів на 20ть :). То ж я поставив в функції вивід $target, щоб глянути де вона хоче створювати каталог.

Побачив наступне:

/home/falcon/data/www/blog.stfalcon.com/wp-content/uploads/2008/11
/home/falcon/data/www/blog.stfalcon.com/wp-content/uploads/2008
/home/falcon/data/www/blog.stfalcon.com/wp-content/uploads
/home/falcon/data/www/blog.stfalcon.com/wp-content
/home/falcon/data/www/blog.stfalcon.com
/home/falcon/data/www
/home/falcon/data
/home/falcon
/home
/
/
/
/
/
/
/
/
/
/
/
/
/
/
/

і т.д.

Функція намагається створити каталог за заданим шляхом, якщо в неї це не виходить, то вона намагається створити каталог на рівень вище і т.д. – цікава така функція. Ну добре, мабуть так було потрібно. Але було б логічно зупинитися при досягненні кореня веб-сервера. Вона ж, натомість, рекурсивно викликається і викликається, поки час виконання скрипта не перевищить max_execution_time встановленний в php.ini.

Відписали про баг на trac.wordpress.org. Писав Сашка, бо мені, з моїми знаннями англійської, тільки hello world на парканах писати :).

Сама ж проблема вирішилась зміною шляху в опції upload_dir в wp_options (на новому сервері шлях трохи змінився).

UPD: Тікет прожив 4,5 години :).

11/29/08 23:24:20 changed by westi

* status changed from assigned to closed.
* resolution set to fixed.

(In [9970]) Break out if we ever make it too far from home. Fixes #8428 props st_falcon.

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>