select の話で危なそうなのは何だろうか?
とりあえず UDP を listen してるのを調べる。
# lsof|grep UDP dhclient 292 root 7u IPv4 237 UDP *:bootpc portmap 296 daemon 5u IPv4 291 UDP *:sunrpc inetd 417 root 7u IPv4 544 UDP *:discard
ふむ。なんか inetd は危なそうな気がする。
と、思ってソースを見てみるとなんとちゃんと nonblocking I/O を使っている、 というか、あのスレッドで気づいて Debian Bug #275585 で直したらしい。
再現実験をしてみる。
% strace ruby -rsocket -e ' u = UDPSocket.new u.bind("0.0.0.0", 30000) IO.select([u]) u.recvfrom(4096)' ... socket(PF_INET, SOCK_DGRAM, IPPROTO_IP) = 3 bind(3, {sa_family=AF_INET, sin_port=htons(30000), sin_addr=inet_addr("0.0.0.0")}, 16) = 0 select(4, [3], NULL, NULL, NULL select(4, [3], [], [], NULL) = 1 (in [3]) recvfrom(3, 0x814eb30, 4096, 0, 0xbfffdc40, 0xbfffdc34) = -1 EAGAIN (Resource temporarily unavailable) gettimeofday({1112674832, 129316}, NULL) = 0 select(5, [3], [], [], NULL
というように UDP を待って、
# hping2 --udp -c 1 -p 30000 -b hostname
として checksum が壊れた UDP パケットを送り込む。
すると、linux 2.6.8 を動かしているところでは
select(4, [3], NULL, NULL, NULL) = 1 (in [3]) recvfrom(3,
となってブロックするのが観察される。
また、linux 2.4.25 を動かしているところでは
select(4, [3], NULL, NULL, NULL) = 1 (in [3]) recvfrom(3, 0x814b248, 4096, 0, 0xbfffe390, 0xbfffe384) = -1 EAGAIN (Resource temporarily unavailable) select(4, [3], NULL, NULL, NULL
となる。このカーネルは O_NONBLOCK がついていなくても EAGAIN を返すわけである。
なお、再度 select が起動しているのは UDPSocket#recvfrom が EAGAIN を隠蔽していることを意味している。 これはユーザが EAGAIN を気にしなくていいということを意味するので、おそらく望ましい挙動である。
さゆリンの 2巻
おかゆネタが減ったような気がする
% google-count よ{,ー}か{,ー}ん 12300 よかん 54600 よかーん 13400 よーかん 504 よーかーん
xxx-j.html などという名前で、日本語であることを示すことがある。
ふと、j を使ってもおかしくない言語が他に何があるのか調べてみる。
... ISO 639 には、Javanese (ジャワ語) しかないようだ。 あまり困りそうにない?
言語コードと国コードが一致しているものはあるか。
% sort -f iso639.txt iso3166.txt | uniq -d -i FJ Fiji TO Tonga
説明の文章まで一致しているのはこんなものか。
説明の文章が微妙に違うだけのはけっこうある。 (German と Germany が de とか)
現実逃避に RFC 1179 を調べる。 プロトコルとしての出来はあまりよくないと感じる。
てきとうにクライアントを書いてみると動いた。
% google-count 白夜 極夜 252000 白夜 1320000 極夜
「白夜」より「極夜」が多いのは感覚に合わない。
調べてみると「"極夜"」とすると変化するので、 「極」と「夜」と分割されているのだろうか。
% google-count --quote 極夜 646 極夜
ただ、空白を入れるだけでも微妙に変わる理由は良く分からない。
% google-count --words 極 夜 1310000 極 夜
(前日から泊まって) 朝一でつくば
(上野で海丼亭)
夕方に赤坂
ふと思ったのだが、 スプレッドシートを表のテンプレートと考えると、 なにか知見が得られるだろうか。
そういえば、LC2005 に出したのが通ったので、6月2日に発表しなければならない
perl の File::Path の rmtree に CAN がふたつある。 http://www.cve.mitre.org/cgi-bin/cvekey.cgi?keyword=rmtree
最近出たほうの fix を読んでみると、chdir を使って書き直してある。 でもなぁ、chdir を使うとスレッドセーフじゃなくなるから、 それはそれで問題が出るのではないだろうか。 まぁ、perl のスレッドはまだデフォルトじゃなかったはずだし、 セキュリティ問題ではないからいいというのかもしれないが。
とはいえ、chdir を使わずに安全な rmtree を書けるかというと、微妙なところではある。 directory をどんどん 700 にしていけばある程度可能な気がしないでもないが。
perl で検索して眺めると、 fork したときに乱数が初期化されないというのがあることに気がつく。 うぅむ。
乱数の件を調べてみると、 perl -le 'fork; print rand' というので同じ値が出て来るのが問題のようである。
perl -le 'rand; fork; print rand' とすればいまでも同じ値が出て来るが、それは問題視されていない、か?
TOCTTOU というのは time-of-check-to-time-of-use の略だということを知る。
Model Checking An Entire Linux Distribution for Security Violations によれば、 状況によっては再帰的にファイルを削除するのが危険なのは UNIX の民間伝承でよく知られた話らしい。
Another example comes from UNIX folklore. It is well known that the root user should not recursively remove files inside directories that may be writable by other users. For example, "rm -rf" is a dangerous command, even if root has verified that the directory /tmp contains no symlink to other parts of the file system. The reason is that after rm verifies that a directory is not a symlink but before it enters the directory to delete the files within, an adversary may replace the directory with a symlink to another part of the file system, therefore tricking rm into deleting that part of the file system.
ふと、[ruby-core:4751] の x86-64 でのトラブルを再現させてみる
% cat a.c extern int f(int arg); int main(int argc, char **argv) { f(100); f(100); return 0; } % cat b.c int f(int arg, ...) { return arg; } % gcc a.c b.c % ./a.out zsh: segmentation fault ./a.out
rm -r が bugtraq で話題になったのが 2000年
open に O_NOFOLLOW を渡せる OS がある
FreeBSD は 3.0-CURRENT からある? http://archives.neohapsis.com/archives/freebsd/2000-06/0089.html
Linux は FreeBSD から取り入れた模様 http://www.ussg.iu.edu/hypermail/linux/kernel/9810.2/1143.html
OpenBSD は 2.7 で取り入れたが、あまりお勧めという感じではない http://www.openbsd.org/plus27.html
For open(2), add a O_NOFOLLOW flag for dealing with symbolic links. This should not be used by generic software -- only use this for very rare and specific problems.
NetBSD は取り入れたもののその有効性に疑問を持っているようだ。 議論は tech-kern 2000-12 のあたりだろうか?
open(2): O_NOFOLLOW If last path element is a symlink, don't follow it. This option is provided for compatibility with other operating systems, but its security value is question- able.
Solaris 10 にもある模様 http://docs.sun.com/app/docs/doc/816-5167/6mbb2jait?a=view
open に O_DIRECTORY を渡せる OS がある
Linux だけ?
path/. を open するのに比べて利点は何か?
Solaris 9 には openat というものがある
fchownat, fstatat, futimesat, renameat, unlinkat というものもある模様
このへんを使うとカレントディレクトリに依存せずに相対パスを使える感じ
fsattr 関係なのか?
fdopendir というのもあるか
openat は reiser4 関連の議論でちょっと出ている
Linus は好意的な感じ
fchdir で実装できるし /proc でも実装できるという意見もある
NetBSD でも議論されていて、好意的な感じ
久しぶりに samidare で core を吐く
最後に吐いたのが 2/22 だったから、2ヶ月以上間が空いている
そろそろ -O3 -march=pentium3 -mcpu=pentium3 だと問題が起きないのではないかと思い始めていたところだったのに
% google-count げ{,ー}ろ{,ー}げ{,ー}ろ 14300 げろげろ 5360 げろげーろ 275 げろーげろ 3 げろーげーろ 1090 げーろげろ 690 げーろげーろ 2 げーろーげろ 125 げーろーげーろ
[latest]