Uber-Uploader 6.8.2 についてはUber-Uploader 6.8.2 の使い方(その1)で述べているので,参考にしてみて欲しい。
Uber-Uploader 6.8.2 を使っているが,いつからかはわからないが 2015/12 に気づいたら動かなくなっていた。
症状としては,アップロードをしようとはするが,
Failed to assign CGI temp directory: Inappropriate ioctl for deviceと表示が出て止まってしまった。
この表示を見る限り,cgi ルーチンが temporary directory 関連のエラーを起こしていそう,というがわかった。 しかし,それだけだと情報が足りないので,次に /var/log/httpd-error.log のログを見てみた。 すると,下記のようなエラーが表示された。
------------------------------------------------
private_tempfiles has been deprecated at /usr/local/lib/perl5/site_perl/CGI.pm line 3213.
Died on line 162 at /usr/xxxx/xxxx/uber_uploader/cgi-bin/ubr_upload.pl line 803.
[Thu Dec 17 17:48:24.527624 2015] [cgid:error] [pid 75620] (32)Broken pipe: [client aaa.bbb.ccc.ddd:57696] AH02651: Error writing request body to script usr/xxxx/xxxx/uber_uploader/cgi-bin/ubr_upload.pl, referer: http://xxx.yyy.zzz.jp/uber_uploader/
------------------------------------------------
わかりにくいが,これは3行の文章で,1行目は CGI.pm の中で「private_tempfiles」は非推奨と言われているみたいだった。 2行目は ubr_upload.pl の 803 行目で止まった,と書いてある。 3行目はよくわからないが,とりあえず ubr_upload.pl でエラーが起こっている,ということを意味していることだけはわかった。
いずれにせよ「ubr_upload.pl」がエラーを起こしているので,その中を見てみることにした。 最終的に「Failed to assign CGI temp directory: Inappropriate ioctl for device」と表示が出るので, ubr_upload.pl の中でその表示をしている部分を探してみた。 すると,156 行から 163 行にかけて,
# Disable private temp files CGI::private_tempfiles(0); # Tell CGI.pm to use our directory based on upload id if($TempFile::TMPDIRECTORY){ $TempFile::TMPDIRECTORY = $temp_dir_id; } elsif($CGITempFile::TMPDIRECTORY){ $CGITempFile::TMPDIRECTORY = $temp_dir_id; } else{ &kak("Failed to assign CGI temp directory: $!", 1, __LINE__); }という部分があった。
どうやら,ここが問題らしい。 しかし,なぜ急にここがエラーになったかが最初わからなかった。 ただ「CGI.pm では private_tempfiles が非推奨になった」みたいなエラーがあったので,CGI.pm が更新されたのが原因だと推測できた。 そうなると,CPAN の CGI.pm のページを見ないといけない。
2015/12/17 現在,CGI.pm は version 4.22 が最新みたいだった。 そこで,CGI モジュールのページを見てみた。 より具体的には CGI モジュールの Changes in temporary file handling (v4.05+)に記載がある。 その中に書いてあることは,細かい点まで理解しきれていないが,どうやら「CGI::File::Temp」を廃止して,「File::Temp」を利用するように変更した,ということみたいだった。 上記の 156 行から 163 行の後半部分では「$TempFile」という変数に,こちらで指定した temporary directory を代入するように書いてあるが, 「CGI::File::Temp」が廃止されたことで,この「$TempFile」という変数が定義されていないみたいだった。
そこで File::Temp を見てみた。 すると「File::Temp」モジュールの中の「tempdir」という関数を ubr_upload.pl に import して,156 - 163 行の代わりに使えばいいみたいだった。 具体的には ubr_upload.pl の最初の方に
use File::Temp qw/tempdir/;と記載し,さらに上記の 156-163 行を全て消して,代わりに
tempdir (DIR => $temp_dir_id);と書いておくことで,うまく temporary directory の問題は回避できた。
ちなみに ubr_upload.pl にエラーがある場合は,
ERROR: Failed to find flength fileと表示が出る。逆に言うと,上記のエラーが出た場合は ubr_upload.pl にエラーがある場合があると思っておいた方がいい。
さらに,この問題と直接関係はないが,/var/log/httpd-error.log を見ていると,
CGI::param called in list context from /usr/xxxx/xxxx/uber_uploader/cgi-bin/ubr_upload.pl line 822, this can lead to vulnerabilities. See the warning in "Fetching the value or values of a single named parameter" at /usr/local/lib/perl5/site_perl/CGI.pm line 404.というエラーが沢山出ていた。 これも CGI モジュールのページを見ると記載があった。 どうやら param() 関数は使い方によっては脆弱性の原因となるので,multi_param() 関数を使うなどで回避しなさい,とあった。 ubr_load.pl では 711 行目の
my @post_values = $query->param($key);でエラーを吐いていた。 そこで,この行の param を multi_param に置き換えるとエラーが消えた。
ということで,最終的に以下のように patch を当てるとよかった。
--- ubr_upload.pl.original 2010-07-24 xx:yy:54.000000000 +0900 +++ ubr_upload.pl 2015-12-17 xx:yy:06.000000000 +0900 @@ -25,6 +25,8 @@ # along with Uber-Uploader. If not, see http://www.gnu.org/licenses/. # #********************************************************************************************************************************** +# 2015/12/17 CGI.pm (v 4.22) caused "temporary directory" error. ==> modified +#********************************************************************************************************************************** #********************************************************************************************************************************** # ATTENTION: THE $TEMP_DIR AND $DATA_DELIMITER VALUES MUST BE DUPLICATED IN THE "UBR_INI.PHP" FILE @@ -44,6 +46,9 @@ use File::Copy; # Module for moving uploaded files use File::Path; # Module for creating and removing directories use IO::File; # Module for file IO +## ======================================================= +use File::Temp qw/tempdir/; # Module for temporary file and directory +## ======================================================= # Makes %ENV safer $ENV{'PATH'} = '/bin:/usr/bin:/usr/local/bin'; @@ -153,13 +158,7 @@ my $hook_query = CGI->new(\&hook, $hook_handle); } else{ - # Disable private temp files - CGI::private_tempfiles(0); - - # Tell CGI.pm to use our directory based on upload id - if($TempFile::TMPDIRECTORY){ $TempFile::TMPDIRECTORY = $temp_dir_id; } - elsif($CGITempFile::TMPDIRECTORY){ $CGITempFile::TMPDIRECTORY = $temp_dir_id; } - else{ &kak("Failed to assign CGI temp directory: $!", 1, __LINE__); } + tempdir (DIR => $temp_dir_id); # tempdir is a function which defined in File::Temp } # Timestamp start of upload @@ -708,7 +707,7 @@ #Write post values foreach my $key (@names){ - my @post_values = $query->param($key); + my @post_values = $query->multi_param($key); foreach my $post_value (@post_values){ $post_value =~ s/&/&/g;
念の為に書いておくが,patch は unified 形式なので
patch -u ubr_upload.pl < patch.20151217のようにすればよい(もっと省略できるような気もするが…)
1 件のコメント:
Thanks a big bunch for fixing this and posting it. Even though I cannot read your language, thanks to the patch I could fix my Uber-Uploader. Eventually, I'm going to ditch it but it's very nice to have it working again in the meantime.
コメントを投稿