Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 5f52b9eb authored by Xin Long's avatar Xin Long Committed by Greg Kroah-Hartman
Browse files

sctp: free cmd->obj.chunk for the unprocessed SCTP_CMD_REPLY



[ Upstream commit be7a7729207797476b6666f046d765bdf9630407 ]

This patch is to fix a memleak caused by no place to free cmd->obj.chunk
for the unprocessed SCTP_CMD_REPLY. This issue occurs when failing to
process a cmd while there're still SCTP_CMD_REPLY cmds on the cmd seq
with an allocated chunk in cmd->obj.chunk.

So fix it by freeing cmd->obj.chunk for each SCTP_CMD_REPLY cmd left on
the cmd seq when any cmd returns error. While at it, also remove 'nomem'
label.

Reported-by: default avatar <syzbot+107c4aff5f392bf1517f@syzkaller.appspotmail.com>
Fixes: 1da177e4 ("Linux-2.6.12-rc2")
Signed-off-by: default avatarXin Long <lucien.xin@gmail.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent f5c8c211
Loading
Loading
Loading
Loading
+18 −10
Original line number Diff line number Diff line
@@ -1373,8 +1373,10 @@ static int sctp_cmd_interpreter(enum sctp_event event_type,
			/* Generate an INIT ACK chunk.  */
			new_obj = sctp_make_init_ack(asoc, chunk, GFP_ATOMIC,
						     0);
			if (!new_obj)
				goto nomem;
			if (!new_obj) {
				error = -ENOMEM;
				break;
			}

			sctp_add_cmd_sf(commands, SCTP_CMD_REPLY,
					SCTP_CHUNK(new_obj));
@@ -1396,7 +1398,8 @@ static int sctp_cmd_interpreter(enum sctp_event event_type,
			if (!new_obj) {
				if (cmd->obj.chunk)
					sctp_chunk_free(cmd->obj.chunk);
				goto nomem;
				error = -ENOMEM;
				break;
			}
			sctp_add_cmd_sf(commands, SCTP_CMD_REPLY,
					SCTP_CHUNK(new_obj));
@@ -1443,8 +1446,10 @@ static int sctp_cmd_interpreter(enum sctp_event event_type,

			/* Generate a SHUTDOWN chunk.  */
			new_obj = sctp_make_shutdown(asoc, chunk);
			if (!new_obj)
				goto nomem;
			if (!new_obj) {
				error = -ENOMEM;
				break;
			}
			sctp_add_cmd_sf(commands, SCTP_CMD_REPLY,
					SCTP_CHUNK(new_obj));
			break;
@@ -1780,11 +1785,17 @@ static int sctp_cmd_interpreter(enum sctp_event event_type,
			break;
		}

		if (error)
		if (error) {
			cmd = sctp_next_cmd(commands);
			while (cmd) {
				if (cmd->verb == SCTP_CMD_REPLY)
					sctp_chunk_free(cmd->obj.chunk);
				cmd = sctp_next_cmd(commands);
			}
			break;
		}
	}

out:
	/* If this is in response to a received chunk, wait until
	 * we are done with the packet to open the queue so that we don't
	 * send multiple packets in response to a single request.
@@ -1799,7 +1810,4 @@ static int sctp_cmd_interpreter(enum sctp_event event_type,
		sp->data_ready_signalled = 0;

	return error;
nomem:
	error = -ENOMEM;
	goto out;
}