Description
For a connected AF_UNIX SOCK_STREAM socket whose peer is bound to a filesystem path, getpeername() returns 0 but
does not store the peer address in the supplied sockaddr structure and does not update the address_len value-result
argument. The sun_family field is left as 0 and sun_path is left empty.
AF_INET sockets are not affected and return the peer address correctly.
Expected behavior
getpeername() shall store the peer address in the sockaddr structure pointed to by the address argument and store the
length of this address in the object pointed to by the address_len argument.
Actual behavior
getpeername() returns 0 but leaves the address structure unpopulated (sun_family = 0, sun_path empty) and does not
update address_len.
Observed output:
getpeername(client): ret=0 family=0 path='' len=110
POSIX requirement (if applicable)
POSIX.1-2017 (IEEE Std 1003.1-2017), getpeername(3p), section DESCRIPTION:
"The getpeername() function shall retrieve the peer address of the specified socket, store this address in the sockaddr
structure pointed to by the address argument, and store the length of this address in the object pointed to by the
address_len argument."
Minimal reproduction code
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/socket.h>
#include <sys/un.h>
int main(void)
{
int lfd, cfd, afd, ret;
struct sockaddr_un srv, peer;
socklen_t len;
int flags;
unlink("/tmp/gp_srv");
lfd = socket(AF_UNIX, SOCK_STREAM, 0);
memset(&srv, 0, sizeof(srv));
srv.sun_family = AF_UNIX;
strcpy(srv.sun_path, "/tmp/gp_srv");
bind(lfd, (struct sockaddr *)&srv, sizeof(srv));
listen(lfd, 5);
cfd = socket(AF_UNIX, SOCK_STREAM, 0);
flags = fcntl(cfd, F_GETFL, 0);
fcntl(cfd, F_SETFL, flags | O_NONBLOCK);
connect(cfd, (struct sockaddr *)&srv, sizeof(srv));
afd = accept(lfd, NULL, NULL);
memset(&peer, 0, sizeof(peer));
len = sizeof(peer);
ret = getpeername(cfd, (struct sockaddr *)&peer, &len);
peer.sun_path[sizeof(peer.sun_path) - 1] = '\0';
printf("getpeername(client): ret=%d family=%u path='%s' len=%u\n",
ret, (unsigned)peer.sun_family, peer.sun_path, (unsigned)len);
close(afd);
close(cfd);
close(lfd);
unlink("/tmp/gp_srv");
return 0;
}
Host behavior
getpeername(client): ret=0 family=1 path='/tmp/gp_srv' len=14
Revision
Discovered on 62b46f9
Target
Reproduced on ia32-generic-qemu, not tested on other targets yet.
Related tests
phoenix-rtos-tests/libc/socket/getpeername.c
These tests are currently skipped on the affected target. After applying a fix, re-enable them and re-run the suite to
verify the fix.
Description
For a connected
AF_UNIXSOCK_STREAMsocket whose peer is bound to a filesystem path,getpeername()returns0butdoes not store the peer address in the supplied
sockaddrstructure and does not update theaddress_lenvalue-resultargument. The
sun_familyfield is left as0andsun_pathis left empty.AF_INETsockets are not affected and return the peer address correctly.Expected behavior
getpeername()shall store the peer address in thesockaddrstructure pointed to by the address argument and store thelength of this address in the object pointed to by the
address_lenargument.Actual behavior
getpeername()returns0but leaves the address structure unpopulated (sun_family= 0,sun_pathempty) and does notupdate
address_len.Observed output:
POSIX requirement (if applicable)
POSIX.1-2017 (IEEE Std 1003.1-2017), getpeername(3p), section DESCRIPTION:
"The getpeername() function shall retrieve the peer address of the specified socket, store this address in the sockaddr
structure pointed to by the address argument, and store the length of this address in the object pointed to by the
address_len argument."
Minimal reproduction code
Host behavior
Revision
Discovered on 62b46f9
Target
Reproduced on ia32-generic-qemu, not tested on other targets yet.
Related tests
phoenix-rtos-tests/libc/socket/getpeername.cThese tests are currently skipped on the affected target. After applying a fix, re-enable them and re-run the suite to
verify the fix.