Commit ae3b06ed authored by David S. Miller's avatar David S. Miller
Browse files

Merge branch 'sctp_do_bind-leak'



Mao Wenan says:

====================
fix memory leak for sctp_do_bind

First two patches are to do cleanup, remove redundant assignment,
and change return type of sctp_get_port_local.
Third patch is to fix memory leak for sctp_do_bind if failed
to bind address.

v2: add one patch to change return type of sctp_get_port_local.
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 8f6617ba 29b99f54
...@@ -309,7 +309,7 @@ static int sctp_bind(struct sock *sk, struct sockaddr *addr, int addr_len) ...@@ -309,7 +309,7 @@ static int sctp_bind(struct sock *sk, struct sockaddr *addr, int addr_len)
return retval; return retval;
} }
static long sctp_get_port_local(struct sock *, union sctp_addr *); static int sctp_get_port_local(struct sock *, union sctp_addr *);
/* Verify this is a valid sockaddr. */ /* Verify this is a valid sockaddr. */
static struct sctp_af *sctp_sockaddr_af(struct sctp_sock *opt, static struct sctp_af *sctp_sockaddr_af(struct sctp_sock *opt,
...@@ -399,9 +399,8 @@ static int sctp_do_bind(struct sock *sk, union sctp_addr *addr, int len) ...@@ -399,9 +399,8 @@ static int sctp_do_bind(struct sock *sk, union sctp_addr *addr, int len)
* detection. * detection.
*/ */
addr->v4.sin_port = htons(snum); addr->v4.sin_port = htons(snum);
if ((ret = sctp_get_port_local(sk, addr))) { if (sctp_get_port_local(sk, addr))
return -EADDRINUSE; return -EADDRINUSE;
}
/* Refresh ephemeral port. */ /* Refresh ephemeral port. */
if (!bp->port) if (!bp->port)
...@@ -413,11 +412,13 @@ static int sctp_do_bind(struct sock *sk, union sctp_addr *addr, int len) ...@@ -413,11 +412,13 @@ static int sctp_do_bind(struct sock *sk, union sctp_addr *addr, int len)
ret = sctp_add_bind_addr(bp, addr, af->sockaddr_len, ret = sctp_add_bind_addr(bp, addr, af->sockaddr_len,
SCTP_ADDR_SRC, GFP_ATOMIC); SCTP_ADDR_SRC, GFP_ATOMIC);
/* Copy back into socket for getsockname() use. */ if (ret) {
if (!ret) { sctp_put_port(sk);
inet_sk(sk)->inet_sport = htons(inet_sk(sk)->inet_num); return ret;
sp->pf->to_sk_saddr(addr, sk);
} }
/* Copy back into socket for getsockname() use. */
inet_sk(sk)->inet_sport = htons(inet_sk(sk)->inet_num);
sp->pf->to_sk_saddr(addr, sk);
return ret; return ret;
} }
...@@ -7999,7 +8000,7 @@ static void sctp_unhash(struct sock *sk) ...@@ -7999,7 +8000,7 @@ static void sctp_unhash(struct sock *sk)
static struct sctp_bind_bucket *sctp_bucket_create( static struct sctp_bind_bucket *sctp_bucket_create(
struct sctp_bind_hashbucket *head, struct net *, unsigned short snum); struct sctp_bind_hashbucket *head, struct net *, unsigned short snum);
static long sctp_get_port_local(struct sock *sk, union sctp_addr *addr) static int sctp_get_port_local(struct sock *sk, union sctp_addr *addr)
{ {
struct sctp_sock *sp = sctp_sk(sk); struct sctp_sock *sp = sctp_sk(sk);
bool reuse = (sk->sk_reuse || sp->reuse); bool reuse = (sk->sk_reuse || sp->reuse);
...@@ -8109,7 +8110,7 @@ pp_found: ...@@ -8109,7 +8110,7 @@ pp_found:
if (sctp_bind_addr_conflict(&ep2->base.bind_addr, if (sctp_bind_addr_conflict(&ep2->base.bind_addr,
addr, sp2, sp)) { addr, sp2, sp)) {
ret = (long)sk2; ret = 1;
goto fail_unlock; goto fail_unlock;
} }
} }
...@@ -8181,7 +8182,7 @@ static int sctp_get_port(struct sock *sk, unsigned short snum) ...@@ -8181,7 +8182,7 @@ static int sctp_get_port(struct sock *sk, unsigned short snum)
addr.v4.sin_port = htons(snum); addr.v4.sin_port = htons(snum);
/* Note: sk->sk_num gets filled in if ephemeral port request. */ /* Note: sk->sk_num gets filled in if ephemeral port request. */
return !!sctp_get_port_local(sk, &addr); return sctp_get_port_local(sk, &addr);
} }
/* /*
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment