Patchwork [Lucid,CVE,1/2] sctp: deal with multiple COOKIE_ECHO chunks

login
register
mail settings
Submitter Luis Henriques
Date Aug. 1, 2013, 1:32 p.m.
Message ID <1375363951-5208-2-git-send-email-luis.henriques@canonical.com>
Download mbox | patch
Permalink /patch/264018/
State New
Headers show

Comments

Luis Henriques - Aug. 1, 2013, 1:32 p.m.
From: Max Matveev <makc@redhat.com>

CVE-2013-2206

BugLink: http://bugs.launchpad.net/bugs/1194445

Attempt to reduce the number of IP packets emitted in response to single
SCTP packet (2e3216cd) introduced a complication - if a packet contains
two COOKIE_ECHO chunks and nothing else then SCTP state machine corks the
socket while processing first COOKIE_ECHO and then loses the association
and forgets to uncork the socket. To deal with the issue add new SCTP
command which can be used to set association explictly. Use this new
command when processing second COOKIE_ECHO chunk to restore the context
for SCTP state machine.

Signed-off-by: Max Matveev <makc@redhat.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
(back ported from commit d5ccd496601b8776a516d167a6485754575dc38f)
Signed-off-by: Luis Henriques <luis.henriques@canonical.com>
---
 include/net/sctp/command.h | 1 +
 net/sctp/sm_sideeffect.c   | 3 +++
 net/sctp/sm_statefuns.c    | 6 ++++++
 3 files changed, 10 insertions(+)
Brad Figg - Aug. 2, 2013, 7:23 a.m.
On 08/01/2013 02:32 PM, Luis Henriques wrote:
> From: Max Matveev <makc@redhat.com>
>
> CVE-2013-2206
>
> BugLink: http://bugs.launchpad.net/bugs/1194445
>
> Attempt to reduce the number of IP packets emitted in response to single
> SCTP packet (2e3216cd) introduced a complication - if a packet contains
> two COOKIE_ECHO chunks and nothing else then SCTP state machine corks the
> socket while processing first COOKIE_ECHO and then loses the association
> and forgets to uncork the socket. To deal with the issue add new SCTP
> command which can be used to set association explictly. Use this new
> command when processing second COOKIE_ECHO chunk to restore the context
> for SCTP state machine.
>
> Signed-off-by: Max Matveev <makc@redhat.com>
> Signed-off-by: David S. Miller <davem@davemloft.net>
> (back ported from commit d5ccd496601b8776a516d167a6485754575dc38f)
> Signed-off-by: Luis Henriques <luis.henriques@canonical.com>
> ---
>   include/net/sctp/command.h | 1 +
>   net/sctp/sm_sideeffect.c   | 3 +++
>   net/sctp/sm_statefuns.c    | 6 ++++++
>   3 files changed, 10 insertions(+)
>
> diff --git a/include/net/sctp/command.h b/include/net/sctp/command.h
> index 2c55a7e..0edc14d 100644
> --- a/include/net/sctp/command.h
> +++ b/include/net/sctp/command.h
> @@ -108,6 +108,7 @@ typedef enum {
>   	SCTP_CMD_UPDATE_INITTAG, /* Update peer inittag */
>   	SCTP_CMD_SEND_MSG,	 /* Send the whole use message */
>   	SCTP_CMD_SEND_NEXT_ASCONF, /* Send the next ASCONF after ACK */
> +	SCTP_CMD_SET_ASOC,	 /* Restore association context */
>   	SCTP_CMD_LAST
>   } sctp_verb_t;
>
> diff --git a/net/sctp/sm_sideeffect.c b/net/sctp/sm_sideeffect.c
> index ed742bf..992533a 100644
> --- a/net/sctp/sm_sideeffect.c
> +++ b/net/sctp/sm_sideeffect.c
> @@ -1676,6 +1676,9 @@ static int sctp_cmd_interpreter(sctp_event_t event_type,
>   		case SCTP_CMD_SEND_NEXT_ASCONF:
>   			sctp_cmd_send_asconf(asoc);
>   			break;
> +		case SCTP_CMD_SET_ASOC:
> +			asoc = cmd->obj.asoc;
> +			break;
>   		default:
>   			printk(KERN_WARNING "Impossible command: %u, %p\n",
>   			       cmd->verb, cmd->obj.ptr);
> diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c
> index 2f8e1c8..9e4e846 100644
> --- a/net/sctp/sm_statefuns.c
> +++ b/net/sctp/sm_statefuns.c
> @@ -2048,6 +2048,12 @@ sctp_disposition_t sctp_sf_do_5_2_4_dupcook(const struct sctp_endpoint *ep,
>   	sctp_add_cmd_sf(commands, SCTP_CMD_NEW_ASOC, SCTP_ASOC(new_asoc));
>   	sctp_add_cmd_sf(commands, SCTP_CMD_DELETE_TCB, SCTP_NULL());
>
> +	/* Restore association pointer to provide SCTP command interpeter
> +	 * with a valid context in case it needs to manipulate
> +	 * the queues */
> +	sctp_add_cmd_sf(commands, SCTP_CMD_SET_ASOC,
> +			 SCTP_ASOC((struct sctp_association *)asoc));
> +
>   	return retval;
>
>   nomem:
>

Patch

diff --git a/include/net/sctp/command.h b/include/net/sctp/command.h
index 2c55a7e..0edc14d 100644
--- a/include/net/sctp/command.h
+++ b/include/net/sctp/command.h
@@ -108,6 +108,7 @@  typedef enum {
 	SCTP_CMD_UPDATE_INITTAG, /* Update peer inittag */
 	SCTP_CMD_SEND_MSG,	 /* Send the whole use message */
 	SCTP_CMD_SEND_NEXT_ASCONF, /* Send the next ASCONF after ACK */
+	SCTP_CMD_SET_ASOC,	 /* Restore association context */
 	SCTP_CMD_LAST
 } sctp_verb_t;
 
diff --git a/net/sctp/sm_sideeffect.c b/net/sctp/sm_sideeffect.c
index ed742bf..992533a 100644
--- a/net/sctp/sm_sideeffect.c
+++ b/net/sctp/sm_sideeffect.c
@@ -1676,6 +1676,9 @@  static int sctp_cmd_interpreter(sctp_event_t event_type,
 		case SCTP_CMD_SEND_NEXT_ASCONF:
 			sctp_cmd_send_asconf(asoc);
 			break;
+		case SCTP_CMD_SET_ASOC:
+			asoc = cmd->obj.asoc;
+			break;
 		default:
 			printk(KERN_WARNING "Impossible command: %u, %p\n",
 			       cmd->verb, cmd->obj.ptr);
diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c
index 2f8e1c8..9e4e846 100644
--- a/net/sctp/sm_statefuns.c
+++ b/net/sctp/sm_statefuns.c
@@ -2048,6 +2048,12 @@  sctp_disposition_t sctp_sf_do_5_2_4_dupcook(const struct sctp_endpoint *ep,
 	sctp_add_cmd_sf(commands, SCTP_CMD_NEW_ASOC, SCTP_ASOC(new_asoc));
 	sctp_add_cmd_sf(commands, SCTP_CMD_DELETE_TCB, SCTP_NULL());
 
+	/* Restore association pointer to provide SCTP command interpeter
+	 * with a valid context in case it needs to manipulate
+	 * the queues */
+	sctp_add_cmd_sf(commands, SCTP_CMD_SET_ASOC,
+			 SCTP_ASOC((struct sctp_association *)asoc));
+
 	return retval;
 
 nomem: