On 10/30/20 4:04 AM, Markus Armbruster wrote: >>> + addr->u.q_unix.path = g_strdup(su->sun_path); >> >> This is wrong on at least Linux, where su->sun_path need not be >> NUL-terminated (allowing file-system Unix sockets to have one more byte >> in their name); > > Out of curiosity: is this usage portable? I tried man pages and SUS, no > luck.
On Linux, 'man 7 unix' says: > BUGS > When binding a socket to an address, Linux is one of the implementa‐ > tions that appends a null terminator if none is supplied in sun_path. > In most cases this is unproblematic: when the socket address is > retrieved, it will be one byte longer than that supplied when the > socket was bound. However, there is one case where confusing behavior > can result: if 108 non-null bytes are supplied when a socket is bound, > then the addition of the null terminator takes the length of the path‐ > name beyond sizeof(sun_path). Consequently, when retrieving the socket > address (for example, via accept(2)), if the input addrlen argument for > the retrieving call is specified as sizeof(struct sockaddr_un), then > the returned address structure won't have a null terminator in > sun_path. > > In addition, some implementations don't require a null terminator when > binding a socket (the addrlen argument is used to determine the length > of sun_path) and when the socket address is retrieved on these imple‐ > mentations, there is no null terminator in sun_path. along with advice on using strnlen and/or overallocation to handle various cases in a cleaner manner, and the caveat that if you always use a name smaller than sun_path you can avoid the tricky code (at the expense of one byte less in your namespace). -- Eric Blake, Principal Software Engineer Red Hat, Inc. +1-919-301-3226 Virtualization: qemu.org | libvirt.org