[ TOP | Recently ]

2006-10-13 sendmsg

わかった。必要なチェックが2つ足りない。

sys/kern/uipc_usrreq.c の unp_internalize() に渡したパラメタのチェックが甘くて、cm->cmsg_len に CMSG_ALIGN(sizeof(*cm)) 未満の値を入れると

nfds = (cm->cmsg_len - CMSG_ALIGN(sizeof(*cm))) / sizeof(int);

が負になってカーネルがどっか変なメモリ見てpanicで死んでた。NetBSD/amd64で確認。試してないけどたぶん hw.alignbytes = 7 な arch はアウトだ。ソース見る限りOpenBSDもかなぁ。FreeBSDは知らn


ここに CMSG_ALIGN(sizeof(*cm)) 未満な cm->cmsg_len が来るのがおかしいのが一点目。
もう一つ、nfds が 0 な時でも、panic はしないものの、カーネルスタックがユーザランドに見えてしまうのではじくべき。
これが二点目。ただしこっちは KSTACK_MAGIC が見えるだけっぽいので実害なし。


一つ目のチェックは uipc_syscalls.c の sendit() の

if (mp->msg_control) {
	if (mp->msg_controllen < sizeof(struct cmsghdr)) {
		error = EINVAL;

ここがまずいんだな。正解は

if (mp->msg_controllen < __CMSG_ALIGN(sizeof(struct cmsghdr))) {

だ。

二つめのチェックは uipc_usrreq.c の unp_internalize() の nfds = 〜 の個所。

sendprは週末休めたら…


EOF