プロジェクト

全般

プロフィール

Bug(バグ) #2011

PHP 5.2.3〜5.2.5 で openpne:install をおこなうとセグメンテーション違反でインストールに失敗する

Kiwa Sakaiほぼ13年前に追加. 12年以上前に更新.

ステータス:
Fixed(完了)
優先度:
High(高め)
担当者:
対象バージョン:
開始日:
2011-04-21
期日:
進捗率:

100%

3.6 で発生するか:
Yes
3.8 で発生するか:
Unknown (未調査)

説明

概要

PHP 5.2.3〜5.2.5 で openpne:install を実行すると、インストール開始時点でセグメンテーション違反となり、インストールできない。

>> installer start clean install
セグメンテーション違反です

同梱されているセットアップドキュメントを確認すると、動作の想定バージョンはPHP5.2.3以降とある

OpenPNE3 は以下のようなサーバ環境で動作させることを想定しています。

Webサーバ
  Apache
    * mod_rewrite を使用可能
PHP
  PHP5.2.3 以降

note-19 で示されていますが、 PHP5.2.6 以降では、インストール時に問題は生じないようです。

確認バージョン

  • stable-3.6.x ブランチ(beta8 以降で確認している)でかつ PHP5.2.3 - 5.2.5 の環境

OpenPNE-3.4.x では発生せず、 OpenPNE-3.7.0dev でも発生しない(特定の範囲のバージョンの ZendFramework で生じる問題で、それが OpenPNE-3.6.x である)。

詳細は note-20 を参照。

Zend_Uri_Http.patch 表示 (543 Bytes) Maki Takahashi, 2011-07-27 15:35

Zend_Validate_Hostname.patch 表示 (911 KB) Maki Takahashi, 2011-08-05 23:29


関連するチケット

関連している OpenPNE 3 - Backport(バックポート) #2201: php5.2.3・php5.2.4 で openpne:install をおこなうとセグメンテーション違反でインストールに失敗する Invalid(無効) 2011-06-10
関連している OpenPNE 3 - Bug(バグ) #2349: PHP 5.2.3〜5.2.5で国際化ドメイン名を含む URL を利用しようとするとセグメンテーション違反が発生する可能性がある New(新規) 2011-08-13

関係しているリビジョン

リビジョン 70ef9ba5 (差分)
Maki Takahashi12年以上前に追加

(refs #2011) added "IDN domains are not validated" option of Zend_Validate_Hostname if PHP_VERSION < 5.2.6 in openpne:install

履歴

#1 Kiwa Sakaiほぼ13年前に更新

環境の問題かもしれないため確認が必要なので、OpenPNE3.6のバックポートは作成していません。

#2 Shingo Yamadaほぼ13年前に更新

  • 優先度Normal(通常) から High(高め) に変更

#3 Shingo Yamadaほぼ13年前に更新

  • 3.6 で発生するかYes にセット

#4 Shingo Yamadaほぼ13年前に更新

sakaiさんに本件の発生環境を依頼済みです。(amazonEC2, ~5/25)

#5 Minoru Takaiほぼ13年前に更新

  • 対象バージョンOpenPNE 3.7.0 にセット

#6 Shingo Yamadaほぼ13年前に更新

  • 担当者Naoya Tozuka にセット

#7 Shingo Yamadaほぼ13年前に更新

  • ステータスNew(新規) から Accepted(着手) に変更
  • 担当者Naoya Tozuka から Shingo Yamada に変更

#8 Shingo Yamada12年以上前に更新

openpne:install を実行し SegmentationFault が発生するかどうかをPHPのバージョン毎に確認しました。

PHPのバージョン毎に確認結果

  • php-5.2.3 NG
  • php-5.2.4 NG
  • php-5.2.5 NG
  • php-5.2.6 OK
  • php-5.2.8 OK
  • php-5.2.17 OK
定義
  • OK: SegmentationFault 発生せず
  • NG: SegmentationFault 発生
「NG」状態の詳細
下記のタイミングで「Segmentation fault」が発生
  • 「/opt/phpall/bin/php-5.2.x symfony openpne:install」を実施(x ->バージョン)
  • DB接続情報を入力
  • (タスクが走り出す)
  • 「installer start clean install」と表示
  • 直後に「Segmentation fault」が表示され、処理がとまる
  • 「Segmentation fault」発生時の表示
      The Database Port Number :            
      The Database Name        : localhost  
      The Database Socket      :            
    
      Is it OK to start this task? (Y/n)    
    
    y
    >> installer start clean install
    Segmentation fault
    [shingo@csaXXX op36.shingo]$ 
    

#9 Shingo Yamada12年以上前に更新

http://openpne3.com/mediawiki/index.php?title=OpenPNE3%E3%83%8E%E3%82%A6%E3%83%8F%E3%82%A6:SegmentationFault&oldid=462
上記に、以下の報告がありました。

OpenPNE3.6にバンドルされているZend_Http_Clientが原因。 lib/vendor/Zendをzend frameworkの最新版に置き換えると正常にコマンドを完了できる。 

stable-3.6.x でも master と同様下記の操作を行い、最新の「zend framework」で 「Segmentation fault」が発生するかどうかを確認します。

commit 821abff4e86ab2fe50d592f5fe82209e14b653d7
Author: Kousuke Ebihara <ebihara@tejimaya.com>
Date:   Thu Sep 9 16:10:38 2010 +0900

    updated bandled ZendFramework to latest stable release (ZendFramework 1.10.8) (fixes #205)

    I executed the following command:
      $ svn export http://framework.zend.com/svn/framework/standard/tags/release-1.10.8/library/Zend/Acl
      $ svn export http://framework.zend.com/svn/framework/standard/tags/release-1.10.8/library/Zend/Acl.php
      $ svn export http://framework.zend.com/svn/framework/standard/tags/release-1.10.8/library/Zend/Exception
      $ svn export http://framework.zend.com/svn/framework/standard/tags/release-1.10.8/library/Zend/Exception.php
      $ svn export http://framework.zend.com/svn/framework/standard/tags/release-1.10.8/library/Zend/Feed
      $ svn export http://framework.zend.com/svn/framework/standard/tags/release-1.10.8/library/Zend/Feed.php
      $ svn export http://framework.zend.com/svn/framework/standard/tags/release-1.10.8/library/Zend/Http
      $ svn export http://framework.zend.com/svn/framework/standard/tags/release-1.10.8/library/Zend/Http.php
      $ svn export http://framework.zend.com/svn/framework/standard/tags/release-1.10.8/library/Zend/Loader
      $ svn export http://framework.zend.com/svn/framework/standard/tags/release-1.10.8/library/Zend/Loader.php
      $ svn export http://framework.zend.com/svn/framework/standard/tags/release-1.10.8/library/Zend/Mail
      $ svn export http://framework.zend.com/svn/framework/standard/tags/release-1.10.8/library/Zend/Mail.php
      $ svn export http://framework.zend.com/svn/framework/standard/tags/release-1.10.8/library/Zend/Mime
      $ svn export http://framework.zend.com/svn/framework/standard/tags/release-1.10.8/library/Zend/Mime.php
      $ svn export http://framework.zend.com/svn/framework/standard/tags/release-1.10.8/library/Zend/Registry
      $ svn export http://framework.zend.com/svn/framework/standard/tags/release-1.10.8/library/Zend/Registry.php
      $ svn export http://framework.zend.com/svn/framework/standard/tags/release-1.10.8/library/Zend/Search
      $ svn export http://framework.zend.com/svn/framework/standard/tags/release-1.10.8/library/Zend/Search.php
      $ svn export http://framework.zend.com/svn/framework/standard/tags/release-1.10.8/library/Zend/Uri
      $ svn export http://framework.zend.com/svn/framework/standard/tags/release-1.10.8/library/Zend/Uri.php
      $ svn export http://framework.zend.com/svn/framework/standard/tags/release-1.10.8/library/Zend/Validate
      $ svn export http://framework.zend.com/svn/framework/standard/tags/release-1.10.8/library/Zend/Validate.php
      $ svn export http://framework.zend.com/svn/framework/standard/tags/release-1.10.8/library/Zend/Version
      $ svn export http://framework.zend.com/svn/framework/standard/tags/release-1.10.8/library/Zend/Version.php

#10 Shingo Yamada12年以上前に更新

検証結果

#note-9 の内容を実施する前後で動作確認を行った。

before
  • stable-3.6.x / php-5.2.3 : NG
  • stable-3.6.x / php-5.2.6 : OK
after
  • stable-3.6.x / php-5.2.3 : OK
  • stable-3.6.x / php-5.2.6 : OK

上記の結果より、本チケットは ZendFramework 1.10.8 にバージョンアップすることで解決できる問題であるといえる。

#11 Shingo Yamada12年以上前に更新

  • 担当者Shingo Yamada から Maki Takahashi に変更

#12 Maki Takahashi12年以上前に更新

  • ファイル Zend_Uri_Http.patch 表示 を追加
  • ステータスAccepted(着手) から Pending Review(レビュー待ち) に変更
  • 進捗率0 から 50 に変更

#note-9 の通り、OpenPNE3.7.0(masterブランチ)ではZendFramework 1.10.8にバージョンアップされているため、解決済みですが
OpenPNE3.6(stable-3.6.xブランチ)に含まれるZendFramework 1.7.3PL1において

lib/vendor/Zend/ValidateHostname.php 358行目で落ちていることがわかりました。

// Check each domain part
$status = @preg_match($regexLabel, $domainPart);

http://framework.zend.com/manual/ja/zend.validate.set.html#zend.validate.set.hostname.idn
国際化ドメイン名(IDN)を検証しないようにすれば、回避できます。

php5.2.5以降では、国際化ドメインを使用すると「Invalid URI supplied」という例外が発生するようになりますが
Punycode変換すれば上記の例外をさけることが可能です。

lib/vendor/Zend/Uri/Http.phpの446行目

$validate = new Zend_Validate_Hostname(Zend_Validate_Hostname::ALLOW_ALL);

 ↓
$validate = new Zend_Validate_Hostname(Zend_Validate_Hostname::ALLOW_ALL, false);

上記修正パッチを添付いたします。

#13 Shingo Yamada12年以上前に更新

  • 対象バージョンOpenPNE 3.7.0 から OpenPNE3.6beta13 に変更

master では起こらないため、本チケットの対象バージョンを 3.6 に変更します。
作成済みのBPチケットは閉じます。

#14 Rimpei Ogawa12年以上前に更新

  • ステータスPending Review(レビュー待ち) から Rejected(差し戻し) に変更

Zend_Uri_Http を利用している箇所はインストール中に呼ばれるこの箇所だけではないため、「国際化ドメイン名(IDN)を検証しないようにする」という変更を安易にするべきではないと思います。

可能であれば、国際化ドメイン名の検証をした上で Segmentaion fault が発生しないような変更をした方がよいと思いますが、これは難しいでしょうか?
(こちらで少し確認したところ master ブランチ同梱の Zend_Uri_Http でも国際化ドメイン名の検証は行っているようなので不可能ではないと思いますが、Zend_Validate_Hostname がかなり変更されていたので容易ではないかもしれませんね...)

ただ、元々 symfony の sfValidatorUrl や _auto_link_urls() は国際化ドメイン名を考慮しない実装となっているため、これらの機構と一緒に Zend_Uri_Http を利用している箇所については、「国際化ドメイン名(IDN)を検証しないようにする」という変更は影響を受けないため、実際には問題ないケースがほとんどかもしれません。

#15 Maki Takahashi12年以上前に更新

  • ステータスRejected(差し戻し) から Accepted(着手) に変更

masterに同梱されているZendFrameworkを参考にパッチを作り直します。

#16 Shingo Yamada12年以上前に更新

  • 360対象beta13 にセット

#17 Maki Takahashi12年以上前に更新

Zend_Validate_Hostname.phpを修正するパッチを作成し、「国際化ドメイン名の検証」を可能にしました。

が、しかし(これはMasterに同梱されているZendFrameworkでも発生するのですが)php5.2.4にて
Zend_Http_Clientに日本語ドメインを指定した場合、preg_matchでSegmentaion faultが発生するようですので
結果として?(日本語ドメインしか試していませんが)国際化ドメイン名の検証ができない状況のようです。
(ざっと調べただけですがpreg_matchの引数が長過ぎるとダメなようなので、うまい回避方法がなさそうに思われます)

(修正としては不十分に思われますが)
とりあえず、添付のパッチを適用した状態でphp5.2.4にてインストールが正常に動作することは確認済みです。

#18 Rimpei Ogawa12年以上前に更新

関連していると思われる情報メモ:

PHP 5.2.6 で PCRE のバージョンが上がっている。

Version 5.2.6

  • Security Fixes
    • Upgraded PCRE to version 7.6 (Nuno)

http://php.net/ChangeLog-5.php#5.2.6

(※以下の表はChangeLogしか確認せずに作っています)

PHP PCRE
5.2.6 7.6
5.2.5 7.3
5.2.4 7.2
5.2.3 7.0

PCRE 7.6 の ChangeLog にそれらしい変更あり。

Version 7.6 28-Jan-08


1. A character class containing a very large number of characters with

codepoints greater than 255 (in UTF-8 mode, of course) caused a buffer
overflow.

http://www.pcre.org/changelog.txt

#19 Rimpei Ogawa12年以上前に更新

まず、こちらでの調査内容を書きます。(修正方針は次のコメントに分けます)

現在の master に同梱されている https://raw.github.com/openpne/OpenPNE3/master/lib/vendor/Zend/Validate/Hostname/Jp.php を読み込んで preg_match() に渡すだけのテストをしてみたところ、たしかに PHP 5.2.3〜5.2.5 では Segmentation fault が発生していました。

検証コード:

<?php
$jp = include dirname(__FILE__).'/Jp.php';
echo '1 ';
$pattern = $jp[1];
echo '2 ';
preg_match($pattern, '');
echo 'Success'.PHP_EOL;

実行結果:

$ phpall test.php
php-5.2.3: 1 2
php-5.2.4: 1 2
php-5.2.5: 1 2
php-5.2.6: 1 2 Success!
php-5.2.8: 1 2 Success!
php-5.2.9: 1 2 Success!
php-5.2.10: 1 2 Success!
php-5.2.11: 1 2 Success!
php-5.2.12: 1 2 Success!
php-5.2.13: 1 2 Success!
php-5.2.14: 1 2 Success!
php-5.2.15: 1 2 Success!
php-5.2.16: 1 2 Success!
php-5.2.17: 1 2 Success!
php-5.3.0: 1 2 Success!
php-5.3.1: 1 2 Success!
php-5.3.2: 1 2 Success!
php-5.3.3: 1 2 Success!
php-5.3.4: 1 2 Success!
php-5.3.5: 1 2 Success!
php-5.3.6: 1 2 Success!

$ php-5.2.3 test.php
1 2 セグメンテーション違反です
$ php-5.2.4 test.php
1 2 セグメンテーション違反です
$ php-5.2.5 test.php
1 2 セグメンテーション違反です
$ php-5.2.6 test.php
1 2 Success!

よって、Zend Framework 1.10.8 で問題が完全に解決されたわけではなく、master のコードでも国際化ドメイン名の検証が行われると 3.6 同様に Segmentation fault が発生するものと考えられます。

Zend Framework 1.10.8 で本チケットの問題が発生しなくなったのは、IDN検証用の正規表現によるマッチングの前に非IDNのドメイン名検証用の正規表現によるマッチングを行いこれが成功した場合にはIDN検証用の正規表現を利用しないコードに変更されたからです。そのため、以前のバージョンでは全URLに対して Segmentation fault が発生していたのに対し、新しいバージョンでは実際にIDNのURLを利用しようとしない限りは Segmentation fault が発生しなくなったものと思われます。

lib/vendor/Zend/Validate/Hostname.php

/**
 * Match against IDN hostnames
 * Note: Keep label regex short to avoid issues with long patterns when matching IDN hostnames
 * @see Zend_Validate_Hostname_Interface
 */
$regexChars = array(0 => '/^[a-z0-9\x2d]{1,63}$/i');
if ($this->_options['idn'] &&  isset($this->_validIdns[strtoupper($this->_tld)])) {
    if (is_string($this->_validIdns[strtoupper($this->_tld)])) {
        $regexChars += include($this->_validIdns[strtoupper($this->_tld)]);
    } else {
        $regexChars += $this->_validIdns[strtoupper($this->_tld)];
    }
}

...

// Check each domain part
$checked = false;
foreach($regexChars as $regexKey => $regexChar) {
    $status = @preg_match($regexChar, $domainPart);
    if ($status > 0) {
        ...
            $checked = true;
            break;
        ...
    }
}

#20 Rimpei Ogawa12年以上前に更新

  • ステータスPending Review(レビュー待ち) から Rejected(差し戻し) に変更

問題点について整理

PHP 5.2.3〜5.2.5(本チケットのタイトルは 5.2.5 が抜けている)の環境で、

  1. openpne:install をおこなうとセグメンテーション違反でインストールに失敗する
    • Zend_Validate_Hostname を利用するクラス(例えば、Zend_Http_Client)で、特定のドメイン名(※)を含む URL を利用した場合にセグメンテーション違反が発生する
      • (※)国際化ドメイン名を許容し、Zend_Validate_Hostname で用意されている検証用の正規表現が長いもの。例えば、.jp
    • 標準設定では、openpne:install 時に Zend_Http_Client に plugins.openpne.jp を含む URL を渡すために問題が発生する
    • OpenPNE対象ブランチ
      • master ブランチでは発生しない
      • stable-3.6.x ブランチでは発生する
      • stable-3.4.x ブランチではおそらく発生しない(.jp の国際化ドメインに Zend_Validate_Hostname が対応していないため)
  2. (具体的な問題は報告されていないが)国際化ドメイン名を含む URL を利用しようとするとセグメンテーション違反が発生する可能性がある
    • Zend_Validate_Hostname を利用するクラス(例えば、Zend_Http_Client)で、特定のドメイン名(※)の 国際化ドメイン名を含む URL を利用した場合にセグメンテーション違反が発生する
      • (※)国際化ドメイン名を許容し、Zend_Validate_Hostname で用意されている検証用の正規表現が長いもの。例えば、.jp
      • 例えば、 plugins.openpne.jp は問題なく、 日本語.jp は問題がある
    • OpenPNE対象ブランチ
      • master ブランチで発生する
      • stable-3.6.x ブランチで発生する
      • stable-3.4.x ブランチでも発生すると思われるが、対象のドメイン名は master や 3.6 のものとは異なる(.jp は未対応。また、他のドメインに関してもなぜか正規表現が短いものが多いので発生しないかもしれない)

修正方針についての提案

まず、本チケットにおいては 問題1 の openpne:install 時にセグメンテーション違反が発生する問題についてのみ対象とし、問題2 については別チケット扱いとするのがよいと思います。(問題2 については具体的な問題が報告されておらず、国際化ドメイン名が利用されて問題の発生する可能性のある箇所も非常に限られているため、緊急性はないと考えられる)

その上で本チケットの修正内容としては、note-12 のパッチをベースとし、PHPのバージョンを確認し 5.2.6 未満の場合のみ国際化ドメイン名の検証を行わないようにする分岐を追加する方法を提案します。(バージョンの比較には PHP の version_compare() 関数 が使えます)

PHP 5.2.6 以上の環境についてはこれまで通り動作し、PHP 5.2.6 未満の環境においては元々セグメンテーション違反により国際化ドメイン名が利用できない状態であったので、この変更により現状より悪くなることはありません。

また、 note-17 のパッチに比べると小さい変更で済むため、安定版リリース前にも適用しやすいというメリットもあります。

#21 Maki Takahashi12年以上前に更新

  • ステータスRejected(差し戻し) から Accepted(着手) に変更

#22 Maki Takahashi12年以上前に更新

  • 題名php5.2.3・php5.2.4 で openpne:install をおこなうとセグメンテーション違反でインストールに失敗する から PHP 5.2.3〜5.2.5 で openpne:install をおこなうとセグメンテーション違反でインストールに失敗する に変更
  • 説明 を更新 (diff)
  • ステータスAccepted(着手) から Pending Review(レビュー待ち) に変更

70ef9ba5 にて

note-12 のパッチをベースとし、PHPのバージョンを確認し 5.2.6 未満の場合のみ国際化ドメイン名の検証を行わないようにする分岐を追加する方法

を採用しました。

php5.2.4の環境および、php5.3.2の環境両方にてインストールが正常に行えることを確認いたしました。

問題2については、別途チケットを作成しました( #2349

#23 Minoru Takai12年以上前に更新

  • 説明 を更新 (diff)

チケットの Description の一部が古かったので修正

#24 Kousuke Ebihara12年以上前に更新

  • ステータスPending Review(レビュー待ち) から Pending Testing(テスト待ち) に変更
  • 進捗率50 から 70 に変更

#25 Mutsumi Imamura12年以上前に更新

下記のPHPバージョン下でインストールタスクを実行し、実行直後にセグメンテーション違反が発生しないことを確認しました。

  • PHP5.2.3
  • PHP5.2.4
  • PHP5.2.5
  • PHP5.2.6
  • PHP5.2.8
  • PHP5.2.17

テスト実施時に1点気になった点は、PHP5.2.17でインストールタスクを実行したところ、スキーマを読み込む直後くらいにセグメンテーション違反が発生しました。
しかし、再度実行したところ再現せず問題なくインストールすることが出来ました。
このチケットで問題視されていたインストール直後にセグメンテーション違反が発生することとはまた別の問題であると考えられることと、100%再現するというわけではないのでこのチケットは修正完了とします。
別途、チケットを作成し対応するのが望ましいかと思います。

下記はセグメンテーション違反発生時のターミナル出力の一部抜粋です。

>> file+     /home/tetete/sns/php-5.2.17.tetete.jp/data/fixtures_tmp/012_000_revision_51da175b32839d5dc41ab76d63dab10c.yml
>> file+     /home/tetete/sns/php-5.2.17.tetete.jp/data/fixtures_tmp/012_010_navigation_0d7169e208ca9d16a84085575c34d1b9.yml
>> file+     /home/tetete/sns/php-5.2.17.tetete.jp/data/fixtures_tmp/012_020_gadget_854d0f4d0df31fd028b4c8e75a0a6096.yml
>> doctrine  Dropping "doctrine" database
>> doctrine  SQLSTATE[HY000]: General error: 1008 Can't drop database 'tetete'; database doesn't exist. Failing Query: "DROP DATABASE tetete" 
>> doctrine  Creating "prod" environment "doctrine" database
>> doctrine  generating model classes
>> file+     /tmp/doctrine_schema_48626.yml
Segmentation fault

#26 Mutsumi Imamura12年以上前に更新

  • ステータスPending Testing(テスト待ち) から Fixed(完了) に変更
  • 進捗率70 から 100 に変更

テスト実施時に1点気になった点は、PHP5.2.17でインストールタスクを実行したところ、スキーマを読み込む直後くらいにセグメンテーション違反が発生しました。

については↓のチケットで対応することにしましょう。

php-5.2.17の環境でインストールタスクを実行するとセグメンテーション違反が発生する場合がある
http://redmine.openpne.jp/issues/2357

他の形式にエクスポート: Atom PDF