lists.openwall.net | lists / announce owl-users owl-dev john-users john-dev passwdqc-users yescrypt popa3d-users / oss-security kernel-hardening musl sabotage tlsify passwords / crypt-dev xvendor / Bugtraq Full-Disclosure linux-kernel linux-netdev linux-ext4 linux-hardening linux-cve-announce PHC | |
Open Source and information security mailing list archives
| ||
|
Date: Tue, 8 Oct 2013 10:32:09 -0400 From: Steve Rago <sar@...-labs.com> To: Andi Kleen <andi@...stfloor.org> CC: David Miller <davem@...emloft.net>, <luto@...capital.net>, <netdev@...r.kernel.org>, <mtk.manpages@...il.com>, <ebiederm@...ssion.com> Subject: Re: bug in passing file descriptors On 10/07/2013 06:55 PM, Andi Kleen wrote: > David Miller <davem@...emloft.net> writes: > >> From: Steve Rago <sar@...-labs.com> >> Date: Mon, 7 Oct 2013 16:29:15 -0400 >> >>> On 10/07/2013 03:42 PM, David Miller wrote: >>>> There is no compatability issue. >>>> >>>> 32-bit tasks will always see the 4-byte align/length. >>>> 64-bit tasks will always see the 8-byte align/length. >>>> >>> >>> Really? So when I compile my application on a 32-bit Linux box and >>> then try to run it on a 64-bit Linux box, you're not going to overrun >>> my buffer when CMSG_SPACE led me to allocate an insufficient amount of >>> memory needed to account for padding on the 64-bit platform? >> >> We have a compatability layer that gives 32-bit applications the >> same behavior as if they had run on a 32-bit machine. >> >> Search around for the MSG_MSG_COMPAT flag and how that is used in >> net/socket.c > > But it seems the compat layer doesn't handle this correctly, > otherwise Steve's original test case would work. > > Must be a bug somewhere in the compat layer. > > -Andi > I did some research last night and I think the problem stems from an underspecified standard. CMSG_LEN and CMSG_SPACE seem to have originated with RFC 2292, which has since been obsoleted by RFC 3542. The difference is that CMSG_SPACE accounts for padding at the end, which is needed when you stuff multiple cmsghdr objects in the same buffer. CMSG_LEN is required to be used to initialize the cmsg_len member of the structure. When you only have one cmsghdr object in your call to recvmsg, it is unclear whether you need to have a buffer as large as CMSG_SPACE or CMSG_LEN. Historically, BSD-based platforms never had these macros and didn't return the ancillary data if the space provided by the application wasn't big enough. Linux, *which has a bug*, won't copy more bytes than cmsg_len specifies when the application uses CMSG_LEN instead of CMSG_SPACE, but then lies to the application by overwriting msg_controllen. Look in put_cmsg() in net/core/scm.c: "cmlen" is calculated using CM_LEN, and then msg_controllen is checked against it to make sure you don't overwrite the user's buffer. However, in recvmsg(), msg_controllen is overwritten by "msg_sys.msg_control - cmsg_ptr". msg_control was incremented by CMSG_SPACE at the end of scm_detach_fds(). The Linux kernel code seems to copy the right amount of data, even in the compat case, as far as I can tell. The only bug I see is that msg_controllen returns from recvmsg() with the wrong value. Steve -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majordomo@...r.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Powered by blists - more mailing lists