Skip to content

Commit

Permalink
Phonet: fix race for port number in concurrent bind()
Browse files Browse the repository at this point in the history
Allocating a port number to a socket and hashing that socket shall be
an atomic operation with regards to other port allocation. Otherwise,
we could allocate a port that is already being allocated to another
socket.

Signed-off-by: Rémi Denis-Courmont <remi.denis-courmont@nokia.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Rémi Denis-Courmont authored and David S. Miller committed Sep 24, 2009
1 parent ef87979 commit 582b0b6
Showing 1 changed file with 8 additions and 8 deletions.
16 changes: 8 additions & 8 deletions net/phonet/socket.c
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,8 @@ void pn_sock_unhash(struct sock *sk)
}
EXPORT_SYMBOL(pn_sock_unhash);

static DEFINE_MUTEX(port_mutex);

static int pn_socket_bind(struct socket *sock, struct sockaddr *addr, int len)
{
struct sock *sk = sock->sk;
Expand Down Expand Up @@ -140,16 +142,20 @@ static int pn_socket_bind(struct socket *sock, struct sockaddr *addr, int len)
err = -EINVAL; /* attempt to rebind */
goto out;
}
WARN_ON(sk_hashed(sk));
mutex_lock(&port_mutex);
err = sk->sk_prot->get_port(sk, pn_port(handle));
if (err)
goto out;
goto out_port;

/* get_port() sets the port, bind() sets the address if applicable */
pn->sobject = pn_object(saddr, pn_port(pn->sobject));
pn->resource = spn->spn_resource;

/* Enable RX on the socket */
sk->sk_prot->hash(sk);
out_port:
mutex_unlock(&port_mutex);
out:
release_sock(sk);
return err;
Expand Down Expand Up @@ -357,8 +363,6 @@ const struct proto_ops phonet_stream_ops = {
};
EXPORT_SYMBOL(phonet_stream_ops);

static DEFINE_MUTEX(port_mutex);

/* allocate port for a socket */
int pn_sock_get_port(struct sock *sk, unsigned short sport)
{
Expand All @@ -370,9 +374,7 @@ int pn_sock_get_port(struct sock *sk, unsigned short sport)

memset(&try_sa, 0, sizeof(struct sockaddr_pn));
try_sa.spn_family = AF_PHONET;

mutex_lock(&port_mutex);

WARN_ON(!mutex_is_locked(&port_mutex));
if (!sport) {
/* search free port */
int port, pmin, pmax;
Expand Down Expand Up @@ -401,8 +403,6 @@ int pn_sock_get_port(struct sock *sk, unsigned short sport)
else
sock_put(tmpsk);
}
mutex_unlock(&port_mutex);

/* the port must be in use already */
return -EADDRINUSE;

Expand Down

0 comments on commit 582b0b6

Please sign in to comment.