プロフィール

kosaki

Author:kosaki
連絡先はコチラ

ブログ検索
最近の記事
最近のコメント
最近のトラックバック
リンク
カテゴリー
月別アーカイブ
RSSフィード
FC2ブログランキング

スポンサーサイト このエントリーをはてなブックマークに追加

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。


スポンサー広告 | 【--------(--) --:--:--】 | Trackback(-) | Comments(-)

SDの見本紙届いた このエントリーをはてなブックマークに追加

SD7月号の見本紙届いた。今回はレッドハットの人として東海岸雑記など書いた。RHKKのみなさまには大変お世話になりました(ぺこり)
今回一番驚いたのは「レッドハット恵比寿通信」というタイトルだという話で社内手続きを進めていたら、編集さんマジックでいつのまにかタイトルがレッドハットボストン通信に変わってたことかな。アルェー


表紙:
SoftwareDesign-2013年7月号-表紙


記事:
SoftwareDesign-2013年7月号-ボストン通信



関連記事
スポンサーサイト
雑談 | 【2013-06-27(Thu) 13:26:38】 | Trackback:(0) | Comments:(0)

readdir_r は使ってはいけないという話 このエントリーをはてなブックマークに追加

Unixの世界には readdir_r()というAPIがある。readdir()のthread safe バージョンとしばしば紹介されている。
それぞれの関数宣言は以下

http://man7.org/linux/man-pages/man3/readdir_r.3.html

       struct dirent *readdir(DIR *dirp);
int readdir_r(DIR *dirp, struct dirent *entry, struct dirent **result);

struct dirent {
ino_t d_ino; /* inode number */
off_t d_off; /* not an offset; see NOTES */
unsigned short d_reclen; /* length of this record */
unsigned char d_type; /* type of file; not supported
by all file system types */
char d_name[256]; /* filename */
};


ところで、Solarisとかだと d_nameが d_name[1] だったりするので、


name_max = pathconf(dirpath, _PC_NAME_MAX);
if (name_max == -1) /* Limit not defined, or error */
name_max = 255; /* Take a guess */
len = offsetof(struct dirent, d_name) + name_max + 1;
entryp = malloc(len);


などとして、常にmallocで確保しないとポータブルではない。この例はLinuxの manから持ってきたものだが、このコードは問題がある。

"readdir_r considered harmful" [1] http://womble.decadent.org.uk/readdir_r-advisory.html によると以下の脆弱性がある

もし、setuidされた"rd" というプログラムが上記コード片を含んでいたとすると

# ln -sf exploit link && (rd link &; ln -sf /fat link)

pathconf(dirpath) が /fat を相手に行われて FATのrootの最大長は12byteだよーん、などという結果を受け取るので、buffer overflowの脆弱性となる。この場合はinjectionされるのがヒープなので実害がすくないが、allocaを使っていたり、

union {
struct dirent a;
char b[1024];
}


などと横着をしていると目もあてられない事になる。で、回避方法なんだがく、[1] だと BSD由来のdirfd APIでdir streamのfdとってきて fpathconf()でパス最大長取ってこいということになっている。が、もっといい方法がある

Ulrich Drepperが指摘したのだが、そもそも現代のOSではreaddir()はthread safeなんだから、それ使えばええんや。代替関数なんていらんかったんや。と指摘 [2]

http://udrepper.livejournal.com/18555.html

次世代POSIXでは readdir_rは時代遅れとマークされ、readdir()はDIRをスレッド間で共有しない限りスレッドセーフであることが mustになる。これは現状の追認だから誰も困らんだろう。


さて、実は readdir_r には Linux特有のもう1つ困った問題がある。Linuxは前述のとおり d_nameが256 byteになってるから、結構な数のアプリケーションがmalloc()とかせずに、スタックに直接 direntを置いている。普通はこれは問題ない、なぜなら、NAME_MAX は255 でPOSIXの世界でNAME_MAXがヘッダで defineされていたら、ファイルシステムの種類によらず NAME_MAXを超えてはいけないからである。
問題があるというからにはもちろんルールを破っているお馬鹿さんがいるからである。FUSEである。

linux/fs/fuse/fuse_i.h をみると

/** It could be as large as PATH_MAX, but would that have any uses? */
#define FUSE_NAME_MAX 1024


などというふざけたコメントとともに、何故か最大長が1024になっている。これによりfuseがONになっているシステムに readdir_r を使う setsidプロセスがインストールされた場合 root 特権が奪取できる穴が空く可能性がある。

何度でもいうが、スタックオーバーフローはヒープオーバーフローよりヤバいのであって、d_name[] が下手に大きいことによって、dirent がスタックに置かれる危険がましちゃってるのが Linux なのだ。

そういうわけで、アプリケーションデベロッパーのみなさまにおきましては、各自自衛のため、readdir_r()はreaddir()に書き換えていただくよう鋭意努力していだたくとよろしいかと思います。

わたしは今FUSEへこの件のパッチ書いてるんだけど、その話は別件なので、このエントリでは書かない。

おわり


あわせて読みたい: 革命の日々! 効率的なdirectry readingコードについて http://mkosaki.blog46.fc2.com/?no=1008



関連記事
linux | 【2013-06-18(Tue) 21:23:51】 | Trackback:(0) | Comments:(0)

Unix ware - お米 2.0 このエントリーをはてなブックマークに追加

海外で Linux LXCのプレゼン見てると以下の画像を頻繁にみるのですが、日本のみなさまにおかれましては
どこで売っているシロモノか教えてください

Unix ware

なぜか中国のパチモン文化すげえと思われてますが、これは日本のものです(キリリッ

関連記事
雑談 | 【2013-06-18(Tue) 12:08:38】 | Trackback:(0) | Comments:(2)
  1. 無料アクセス解析
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。