2006-10-13 sendmsg
わかった。必要なチェックが2つ足りない。
sys/kern/uipc_usrreq.c の unp_internalize() に渡したパラメタのチェックが甘くて、cm->cmsg_len に CMSG_ALIGN(sizeof(*cm)) 未満の値を入れると
が負になってカーネルがどっか変なメモリ見て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() の
ここがまずいんだな。正解は
だ。
二つめのチェックは uipc_usrreq.c の unp_internalize() の nfds = 〜 の個所。
sendprは週末休めたら…
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