Skip to content

Commit

Permalink
lib/nl: preserve s_local if nl_connect() fails
Browse files Browse the repository at this point in the history
s_local.nl_pid is used to track the generated port unless NL_OWN_PORT is set.
Ensure that getsockname() doesn't overwrite the value and possibly reset
the local port manually to release the generated port.

Signed-off-by: Thomas Haller <thaller@redhat.com>
  • Loading branch information
thom311 committed Mar 5, 2015
1 parent 15824e4 commit 9614acf
Showing 1 changed file with 16 additions and 8 deletions.
24 changes: 16 additions & 8 deletions lib/nl.c
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ int nl_connect(struct nl_sock *sk, int protocol)
int err, flags = 0;
int errsv;
socklen_t addrlen;
struct sockaddr_nl local = { 0 };
char buf[64];

#ifdef SOCK_CLOEXEC
Expand Down Expand Up @@ -163,8 +164,8 @@ int nl_connect(struct nl_sock *sk, int protocol)
}
}

addrlen = sizeof(sk->s_local);
err = getsockname(sk->s_fd, (struct sockaddr *) &sk->s_local,
addrlen = sizeof(local);
err = getsockname(sk->s_fd, (struct sockaddr *) &local,
&addrlen);
if (err < 0) {
NL_DBG(4, "nl_connect(%p): getsockname() failed with %d (%s)\n",
Expand All @@ -173,24 +174,31 @@ int nl_connect(struct nl_sock *sk, int protocol)
goto errout;
}

if (addrlen != sizeof(sk->s_local)) {
if (addrlen != sizeof(local)) {
err = -NLE_NOADDR;
goto errout;
}

if (sk->s_local.nl_family != AF_NETLINK) {
if (local.nl_family != AF_NETLINK) {
err = -NLE_AF_NOSUPPORT;
goto errout;
}

if (sk->s_local.nl_pid != local.nl_pid) {
/* strange, the port id is not as expected. Set the local
* port id to release a possibly generated port and un-own
* it. */
nl_socket_set_local_port (sk, local.nl_pid);
}
sk->s_local = local;
sk->s_proto = protocol;

return 0;
errout:
if (sk->s_fd != -1) {
close(sk->s_fd);
sk->s_fd = -1;
}
if (sk->s_fd != -1) {
close(sk->s_fd);
sk->s_fd = -1;
}

return err;
}
Expand Down

0 comments on commit 9614acf

Please sign in to comment.