diff options
author | Andreas Schneider <asn@samba.org> | 2015-08-05 15:02:49 +0200 |
---|---|---|
committer | Andreas Schneider <asn@samba.org> | 2015-08-11 13:58:30 +0200 |
commit | 85b7f564bd397e82cf847607f0bcee4e35f489ac (patch) | |
tree | 3e6156d7ba11f1d2da91fcb4e82ee62a57dee097 | |
parent | 055eb78f3690008021e17da8714da9db5247308c (diff) | |
download | socket_wrapper-85b7f564bd397e82cf847607f0bcee4e35f489ac.tar.gz socket_wrapper-85b7f564bd397e82cf847607f0bcee4e35f489ac.tar.xz socket_wrapper-85b7f564bd397e82cf847607f0bcee4e35f489ac.zip |
swrap: Correctly update the msg_name in recvmsg()
This has been found while debugging nsupdate.
Signed-off-by: Andreas Schneider <asn@samba.org>
Reviewed-by: Stefan Metzmacher <metze@samba.org>
-rw-r--r-- | src/socket_wrapper.c | 43 |
1 files changed, 30 insertions, 13 deletions
diff --git a/src/socket_wrapper.c b/src/socket_wrapper.c index 1188c4e..bd2798b 100644 --- a/src/socket_wrapper.c +++ b/src/socket_wrapper.c @@ -4051,6 +4051,19 @@ static int swrap_recvmsg_after(int fd, avail += msg->msg_iov[i].iov_len; } + /* Convert the socket address before we leave */ + if (si->type == SOCK_DGRAM && un_addr != NULL) { + rc = sockaddr_convert_from_un(si, + un_addr, + un_addrlen, + si->family, + msg->msg_name, + &msg->msg_namelen); + if (rc == -1) { + goto done; + } + } + if (avail == 0) { rc = 0; goto done; @@ -4096,16 +4109,6 @@ static int swrap_recvmsg_after(int fd, } if (un_addr != NULL) { - rc = sockaddr_convert_from_un(si, - un_addr, - un_addrlen, - si->family, - msg->msg_name, - &msg->msg_namelen); - if (rc == -1) { - goto done; - } - swrap_pcap_dump_packet(si, msg->msg_name, SWRAP_RECVFROM, @@ -4549,9 +4552,6 @@ static ssize_t swrap_recvmsg(int s, struct msghdr *omsg, int flags) ret = libc_recvmsg(s, &msg, flags); - msg.msg_name = omsg->msg_name; - msg.msg_namelen = omsg->msg_namelen; - #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL msg_ctrllen_filled += msg.msg_controllen; msg_ctrllen_left -= msg.msg_controllen; @@ -4593,6 +4593,23 @@ static ssize_t swrap_recvmsg(int s, struct msghdr *omsg, int flags) #endif omsg->msg_iovlen = msg.msg_iovlen; + /* + * From the manpage: + * + * The msg_name field points to a caller-allocated buffer that is + * used to return the source address if the socket is unconnected. The + * caller should set msg_namelen to the size of this buffer before this + * call; upon return from a successful call, msg_name will contain the + * length of the returned address. If the application does not need + * to know the source address, msg_name can be specified as NULL. + */ + if (omsg->msg_name != NULL && + omsg->msg_namelen != 0 && + omsg->msg_namelen >= msg.msg_namelen) { + memcpy(omsg->msg_name, msg.msg_name, msg.msg_namelen); + omsg->msg_namelen = msg.msg_namelen; + } + return ret; } |