bindにoff-by-oneバグ

セキュリティホールだよ。対象はほとんどのバージョン。詳しくは↓を見ておくれ。
http://www.isc.org/index.pl?/sw/bind/bind-security.php

Index: inet_network.c
diff -u inet_network.c:1.5 inet_network.c:1.6
--- inet_network.c:1.5	Wed Apr 27 04:56:21 2005
+++ inet_network.c	Tue Jan 15 04:02:01 2008
@@ -84,9 +84,9 @@
 	}
 	if (!digit)
 		return (INADDR_NONE);
+	if (pp >= parts + 4 || val > 0xffU)
+		return (INADDR_NONE);
 	if (*cp == '.') {
-		if (pp >= parts + 4 || val > 0xffU)
-			return (INADDR_NONE);
 		*pp++ = val, cp++;
 		goto again;
 	}

そんだけの変更かよ!!って思うけどね。しょうがないね。
このinet_network.cっていうソースは、古いBSD由来のコード。bindみたいに昔からあるアプリケーションは、BSD由来のコードを流用していることが多くて、そういう古いソースの中にはoff-by-oneみたいに一見しても気づかない種類のバグが見つかることが多い気がする(調査なんてしてないぜ)。
BSD由来ってことは…?っていう発想は正解。BSDのlibcだって同じソースコードをしてますよ。FreeBSDとかの人はご注意を。BSD系は使ってないから情報は勝手に仕入れておくれ。
で、BSD系のlibcがアウトってことは…?と思うわけで、こういうときに大活躍するgoogleのcodesearchで調べてみたよ。Linux(要するにglibcだ)でもアウトか?って思うじゃん。Solarisも?とか(これはソース持ってないからベンダ情報待ちなんだが)、ともあれ調べた。
http://www.google.co.jp/codesearch
glibc-1.09.1のinet_net.cに同じコードを見つけた。もちろん同じ関数。

	if (*cp == '.') {
		if (pp >= parts + 4)
			return (INADDR_NONE);
		*pp++ = val, cp++;
		goto again;
	}

前後をロクに読んでないから断言はしないけど、アウトっぽいよね。
glibcの1.Xなんて古すぎなので、codesearchで出てきたglibc-2.2.4を見た。

	if (pp >= parts + 4 || val > 0xff)
		return (INADDR_NONE);
	if (*cp == '.') {
		*pp++ = val, cp++;
		goto again;
	}

どう見ても直ってる。bindのページに貼ってあったパッチとまるきり同じ。
おいおい。お前ら、気づいてんなら教えてやれ!glibc-2.2.4って、そうとう前から知ってたんじゃねーか!

っていうかbindもさ、そういう関数はlibcじゃダメっすか。そうですか。libbindはやっぱ必要ですか、そうですか。