From 84080c3caf6efaa7ae85dc3fd1a97acd85ba8afa Mon Sep 17 00:00:00 2001 From: Dan Cross Date: Fri, 15 Jan 2021 03:16:17 +0000 Subject: [PATCH] talk: talk into account sa_len field in sockaddr. `osockaddr` predates the introduction of the sa_len field in `struct sockaddr`. The family has moved to the second field in the structure, but `talk` didn't account for this when it constructs a `sockaddr_in` to send data to another system. The failure case was kind of odd: one could `talk` to a user on, say, a Linux machine, the remote user could respond, and things would work as expected. However, the inverse case, where a user on Linux tried to `talk` to a user on Dragonfly failed: the talk announcement would be made, but an attempt to respond would fail with a protocol error since the `sin_family` field would be zero. Signed-off-by: Dan Cross --- usr.bin/talk/look_up.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/usr.bin/talk/look_up.c b/usr.bin/talk/look_up.c index e1554e155f..5351d93885 100644 --- a/usr.bin/talk/look_up.c +++ b/usr.bin/talk/look_up.c @@ -33,7 +33,9 @@ #include #include #include +#include #include +#include #include "talk_ctl.h" #include "talk.h" @@ -63,11 +65,19 @@ check_local(void) */ current_state = "Waiting to connect with caller"; do { + struct sockaddr_in addr; + struct sockaddr_in *raddr; + if (rp->addr.sa_family != AF_INET) p_error("Response uses invalid network address"); + raddr = (struct sockaddr_in *)&rp->addr; + memset(&addr, 0, sizeof(addr)); + addr.sin_family = AF_INET; + addr.sin_port = raddr->sin_port; + addr.sin_addr = raddr->sin_addr; errno = 0; if (connect(sockt, - (struct sockaddr *)&rp->addr, sizeof (rp->addr)) != -1) + (struct sockaddr *)&addr, sizeof(addr)) != -1) return (1); } while (errno == EINTR); if (errno == ECONNREFUSED) { -- 2.28.0