[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[harden-mac:0170] mount_webdav make ghost.
- To: harden-mac@xxxxxxxxxx
- Subject: [harden-mac:0170] mount_webdav make ghost.
- From: SHIROYAMA Takayuki <puresnow@xxxxxxx>
- Date: Tue, 22 Oct 2002 13:00:54 +0900
しろやまです。
セキュリティーホールって訳じゃないのですが、先日、頭の痛い問題をようやく解き
明かしたので、そのまとめをお送りいたします。
Mac OS X 10.2.2 の WebDAVのマウント機能で 7文字以下のホスト名のサーバを
マウントした場合、存在しないファイルが Finder で見えてしまうという問題がある。
例えば、
http://kirin/
http://angler:10082/
といった感じで、ホスト名の部分が 7 文字以下の場合、
1.そのWebDAV でマウントした直下のディレクトリに名前のない、マウントポイントと
同じアイコンのファイルが見え、それをクリックすると直下のディレクトリと同じ内容が
見える(つまりその無名アイコンも見えて、無限ループできる)
2.そのWebDAVでマウントしたところから下の各フォルダにフォルダと同名のファイル
が表示される。ただし、クリックすると消える
という症状が Finder にて発生します。Terminalからのコマンドラインのアクセスでは、
(少なくともlsでは)該当するファイルは見あたりません。
確認したのは Mac OS X 10.2.1 Jaguar ですが、それ以前の Mac OS X のリリース
でも発生するのかもしれません。
対処法としては 7文字以上の名前でアクセスするとこの問題は発生しません。例えば、
http://61.125.27.157/
http://192.168.12.19:10082/
という風に、同じホストでも IPアドレスで指定したり、
http://kirin.foobar.com/
http://angler.deepsea.org:10082/
という風に長い名前にしてしまえばこの問題は発生しません。
原因:
これは WebDAVのアクセス部分のバグです。 WebDAVは、カーネルにロードされる
モジュール以外に、カーネルにモジュールをロードする load_webdav および
mount_webdav が介在します。特に mount_webdav はその WebDAVサーバが
マウントされている間中動作しており、実際に HTTP によるサーバとの通信を行い、
結果を処理しております。
詳細は Darwin でソースが公開されているので興味を持った方は確認してみてくだ
さい。
問題は、以下のコードにあります。
webdavfs/mount.tproj/webdav_parse.c :1117より
---------------------------------------------------------------
else
{
/* dir_ref did not contain the prefix which meaans it
is a partial uri
* and won't contain the host either, but we need the
host for the inode
* cache, so we will build one
*/
after_dir_ref_hostname = dir_ref;
error = reconstruct_url(hostname, dir_ref, &temp_uri);
if (error)
{
return ENOMEM;
}
decoded_dir_ref = percent_decode(temp_uri);
if (!decoded_dir_ref)
{
free(temp_uri);
return ENOMEM;
}
else
{
free(temp_uri);
}
}
/* Either way, decoded_dir_ref contains a full uri, utf8_decoded
* now lets get past the prefix for the uri we will put in the
inode
* cache */
cache_uri = &decoded_dir_ref[strlen(_WEBDAVPREFIX)];
after_dir_ref_hostname = &cache_uri[strlen(_WEBDAVPREFIX)]; *1
after_dir_ref_hostname = strchr(after_dir_ref_hostname, '/'); *2
---------------------------------------------------------------
これは parse_opendir() という関数の中の処理です。(*1、*2は私が付記しました)
else の前は proxy が入った場合の処理なのでとりあえず忘れます。で、 else 節の
中の reconstruct_url() にて ホスト名、パス(dir_ref) から一旦URLが再構成され
ます。 percent_decode()で URLエンコーディングが解かれ、decoded_dir_ref
に 生のUTF-8の文字列のポインタが渡されます。
# ここで、reconstruct_url()は mount時に渡されたURLにはついていたポート番号
# を知らないため、付記しないことに注意してください。
そして、 _WEBDAVPREFIX の文字列長だけずらされたポイントが cache_uri で
指されます。
_WEBDAVPREFIXは要するに "http://" で、strlen( _WEBDAVPREFIX ) == 7
です。
で、なぜかこの次にもう一回 after_dir_ref_hostname に _WEBDAVPREFIX の
文字列長だけずらされたポイントが代入された後に、strchr()で '/' が捜索されます。
例としてhttp://kirin.foobar.com/ でマウントした場合、WebDAVの起点となる
ディレクトリを opendir() されると
hostname = "kirin.foobar.com"
dir_ref = "/"
decoded_dir_ref="http://kirin.foobar.com/"
cache_uri="kirin.foobar.com/"
*1での after_dir_ref_hostname="oobar.com/"
*2での after_dir_ref_hostname="/"
っとなります。ところが http://kirin/ でマウントされると
hostname = "kirin"
dir_ref = "/"
decoded_dir_ref="http://kirin/"
cache_uri="kirin/"
*1での after_dir_ref_hostname=(NULL)
*2での after_dir_ref_hostname=(NULL)
っとなりました。
# *1、*2 が NULLになったのはたまたまで、何が出るかはわかったものじゃないです。
以上、いずれも mount_webdav に fprintf() を差し込み、daemon() をコメントア
ウトしてバックグラウンドに走るのを阻止した上で実際に検証しました
さて、WebDAVのプロトコルで あるディレクトリ(コレクション)の一覧をとるにはPROPFIND
というメソッドを使います。ここで、Depth:1 ヘッダをつけた PROPFINDメソッドを送る
と、「そのコレクションに入っているもの全てと、そのコレクション自身の情報」を返します。
このため、hrefで示される(ホスト名を除いた)パスを比較することで、ディレクトリ(コレクション)
自身を無視してそれ以外のファイルを「そのディレクトリに含まれるファイル」として処理し
なければならないのですが、先の理由で mount_webdav の中では肝心のパスが間違
っているため、比較に失敗し、「ディレクトリ自身」をディレクトリの中にあるものと勘違い
する模様です。
問題の部分を
---------------------------------------------------------------
cache_uri = &decoded_dir_ref[strlen(_WEBDAVPREFIX)];
after_dir_ref_hostname = strchr(cache_uri, '/');
---------------------------------------------------------------
と書き直して mount_webdav を作り直したところ、7文字以下のホスト名のWebDAV
サーバに対しても問題が起こらず正常にマウントできることが確認できました。
まぁ、IPアドレス直うちでもホスト名は7文字以上になるのですから、普通そんな事態は
起きないとは思いますけど。。。一応、ご報告まで。
さて、これは opendarwin に報告すべきか、Apple に報告すべきか、どっちがいいんでしょ?(^^;
---
SHIROYAMA Takayuki
PS: どっちでもいいから ... 私のコードの方のバグだと思って悩みに悩んだ1ヶ月を、返して...(;_;)
PS/2: 実は、もう一個 webdavにまつわるGhost問題があります。。。
--[PR]------------------------------------------------------------------
┏━━━━━━━━━┓ サイト見たり、アンケートに回答したりすると、
┃ マイポイント.com ┃ ポイントがどんどん貯まっていく面白いサイト!
┃秋のポイント収穫祭┃ 今登録すると、現金10万円や豪華賞品が当たるよ!
┗━━━━━━━━━┛ 早速アクセスしちゃおう!
http://ad.freeml.com/cgi-bin/ad.cgi?id=bv4LW
------------------------------------------------------------------[PR]--
<GMO GROUP> Global Media Online www.gmo.jp