Bug#645469: bind() fails for AF_UNIX sockets with EINVAL
2011/10/16 Jonathan Nieder <jrnieder@gmail.com>:
> Here's "struct sockaddr_un" in eglibc (socket/sys/un.h, after a little
> typedef-chasing):
>
> unsigned char sun_len;
> unsigned char sun_family;
> char sun_path[108]; /* Path name. */
Is this 108 the actual length? ISTR it was just a placeholder.
<sys/un.h> has a macro to determine actual length:
/* Evaluate to actual length of the `sockaddr_un' structure. */
# define SUN_LEN(ptr) ((size_t) (((struct sockaddr_un *) 0)->sun_path) \
+ strlen ((ptr)->sun_path))
Does someone know what this means?
> And here it is in the kernel:
>
> unsigned char sun_len;
> unsigned char sun_family;
> char sun_path[104]; /* Path name. */
>
> I wonder whether there would be any downside to changing that 104 in
> the kernel to 108.
Breaking kernel ABI for everyone not using a patched kernel. Not a good thing.
> Separately from that, it would be helpful to know where the buffer
> overflowed in #645377 is, since maybe it could be made bigger without
> changing the layout of struct sockaddr_un.
I don't think this matters, it's an instance of sockaddr_un. If you
make sun_path[] bigger in the kernel, then instead of 160 you can
overflow it with a larger value (exploit [1] works by declaring its
own sockaddr_un, which has larger sun_path and whose content is not
null-terminated).
The kernel-side of things is now doing the right thing AFAICS.
[1] http://www.exploit-db.com/exploits/17908/
--
Robert Millan
Reply to: