sctp: Free cookie before we memdup a new one [Linux 4.14.129]

sctp: Free cookie before we memdup a new one [Linux 4.14.129]

This Linux kernel change "sctp: Free cookie before we memdup a new one" is included in the Linux 4.14.129 release. This change is authored by Neil Horman <nhorman [at] tuxdriver.com> on Thu Jun 13 06:35:59 2019 -0400. The commit for this change in Linux stable tree is c4964bf (patch) which is from upstream commit ce950f1. The same Linux upstream change may have been applied to various maintained Linux releases and you can find all Linux releases containing changes from upstream ce950f1.

sctp: Free cookie before we memdup a new one

[ Upstream commit ce950f1050cece5e406a5cde723c69bba60e1b26 ]

Based on comments from Xin, even after fixes for our recent syzbot
report of cookie memory leaks, its possible to get a resend of an INIT
chunk which would lead to us leaking cookie memory.

To ensure that we don't leak cookie memory, free any previously
allocated cookie first.

Change notes
v1->v2
update subsystem tag in subject (davem)
repeat kfree check for peer_random and peer_hmacs (xin)

v2->v3
net->sctp
also free peer_chunks

v3->v4
fix subject tags

v4->v5
remove cut line

Signed-off-by: Neil Horman <[email protected]>
Reported-by: [email protected]
CC: Marcelo Ricardo Leitner <[email protected]>
CC: Xin Long <[email protected]>
CC: "David S. Miller" <[email protected]>
CC: [email protected]
Acked-by: Marcelo Ricardo Leitner <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>

There are 8 lines of Linux source code added/deleted in this change. Code changes to Linux kernel are as follows.

 net/sctp/sm_make_chunk.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c
index 4edb4f5..f67df16 100644
--- a/net/sctp/sm_make_chunk.c
+++ b/net/sctp/sm_make_chunk.c
@@ -2586,6 +2586,8 @@ static int sctp_process_param(struct sctp_association *asoc,
    case SCTP_PARAM_STATE_COOKIE:
        asoc->peer.cookie_len =
            ntohs(param.p->length) - sizeof(struct sctp_paramhdr);
+       if (asoc->peer.cookie)
+           kfree(asoc->peer.cookie);
        asoc->peer.cookie = kmemdup(param.cookie->body, asoc->peer.cookie_len, gfp);
        if (!asoc->peer.cookie)
            retval = 0;
@@ -2650,6 +2652,8 @@ static int sctp_process_param(struct sctp_association *asoc,
            goto fall_through;

        /* Save peer's random parameter */
+       if (asoc->peer.peer_random)
+           kfree(asoc->peer.peer_random);
        asoc->peer.peer_random = kmemdup(param.p,
                        ntohs(param.p->length), gfp);
        if (!asoc->peer.peer_random) {
@@ -2663,6 +2667,8 @@ static int sctp_process_param(struct sctp_association *asoc,
            goto fall_through;

        /* Save peer's HMAC list */
+       if (asoc->peer.peer_hmacs)
+           kfree(asoc->peer.peer_hmacs);
        asoc->peer.peer_hmacs = kmemdup(param.p,
                        ntohs(param.p->length), gfp);
        if (!asoc->peer.peer_hmacs) {
@@ -2678,6 +2684,8 @@ static int sctp_process_param(struct sctp_association *asoc,
        if (!ep->auth_enable)
            goto fall_through;

+       if (asoc->peer.peer_chunks)
+           kfree(asoc->peer.peer_chunks);
        asoc->peer.peer_chunks = kmemdup(param.p,
                        ntohs(param.p->length), gfp);
        if (!asoc->peer.peer_chunks)

Leave a Reply

Your email address will not be published. Required fields are marked *