[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

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: