All of lore.kernel.org
 help / color / mirror / Atom feed
From: Vlad Yasevich <vladislav.yasevich@hp.com>
To: Neil Horman <nhorman@tuxdriver.com>
Cc: sri@us.ibm.com, linux-sctp@vger.kernel.org, eteo@redhat.com,
	netdev@vger.kernel.org, davem@davemloft.net, security@kernel.org
Subject: Re: [PATCH]: sctp: Fix skb_over_panic resulting from multiple invalid
Date: Wed, 28 Apr 2010 18:27:11 +0000	[thread overview]
Message-ID: <4BD87DFF.6080502@hp.com> (raw)
In-Reply-To: <20100428181645.GD4818@hmsreliant.think-freely.org>

[-- Attachment #1: Type: text/plain, Size: 2614 bytes --]



Neil Horman wrote:
> On Wed, Apr 28, 2010 at 01:52:05PM -0400, Vlad Yasevich wrote:
>>
>> Vlad Yasevich wrote:
>>> Neil Horman wrote:
>>>> On Wed, Apr 28, 2010 at 10:00:37AM -0400, Vlad Yasevich wrote:
>>>>> I have this patch and a few others already queued.
>>>>>
>>>>> I was planning on sending these today for stable.
>>>>>
>>>>> Here is the full list of stable patches I have:
>>>>>
>>>>> sctp: Fix oops when sending queued ASCONF chunks
>>>>> sctp: fix to calc the INIT/INIT-ACK chunk length correctly is set
>>>>> sctp: per_cpu variables should be in bh_disabled section
>>>>> sctp: fix potential reference of a freed pointer
>>>>> sctp: avoid irq lock inversion while call sk->sk_data_ready()
>>>>>
>>>>> -vlad
>>>>>
>>>> Are you sure?  this oops looks _very_ simmilar to the INIT/INIT-ACK length
>>>> calculation oops described above, but is in fact different, and requires this
>>>> patch, from what I can see.  The right fix might be in the ASCONF chunk patch
>>>> you list above, but I don't see that in your tree at the moment, so I can't be
>>>> sure.
>>> As I said, I totally goofed when reading the description and I apologize.
>>> However, I do one comment regarding the patch.
>>>
>>> If the bad packet is REALLY long (I mean close to 65K IP limit), then
>>> we'll end up allocating a supper huge skb in this case and potentially exceed
>>> the IP length limitation.  Section 11.4 of rfc 4960 allows us to omit some
>>> errors and limit the size of the packet.
>>>
>>> I would recommend limiting this to MTU worth of potentiall errors.  This is
>>> on top of what the INIT-ACK is going to carry, so at most we'll sent 2 MTUs
>>> worth.  That's still a potential by amplification attack, but it's somewhat
>>> mitigated.
>>>
>>> Of course now we have to handle the case of checking for space before adding
>>> an error cause. :)
>>>
>> Hi Neil
>>
>> I am also not crazy about the pre-allocation scheme.  In the case where you have
>> say 100 parameters that are all 'skip' parameters, you'd end up pre-allocating a
>> huge buffer for absolutely nothing.
>>
> Would have been nice if you'd made your opinion known 4 hours ago when I was
> testing version 2 of this. :)
> 

sorry, fighting a head cold and need drugs to think clearly... ;)


>> This is another point toward a fixed error chunk size and let parameter
>> processing allocate it when it reaches a parameter that needs an error.
>>
> Hmm, ok, what would you say to a pathmtu sized chunk allocation in parameter
> processing that drops errors beyond its capacity
> Neil

Here is my quick take on this.  Haven't tested it at all.

-vlad

[-- Attachment #2: neil --]
[-- Type: text/plain, Size: 3987 bytes --]

diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c
index 0fd5b4c..74d8d21 100644
--- a/net/sctp/sm_make_chunk.c
+++ b/net/sctp/sm_make_chunk.c
@@ -1959,8 +1959,10 @@ static void sctp_process_ext_param(struct sctp_association *asoc,
 static sctp_ierror_t sctp_process_unk_param(const struct sctp_association *asoc,
 					    union sctp_params param,
 					    struct sctp_chunk *chunk,
-					    struct sctp_chunk **errp)
+					    struct sctp_chunk **errp,
+					    unsigned int param_cnt)
 {
+	unsigned int needed_bytes;
 	int retval = SCTP_IERROR_NO_ERROR;
 
 	switch (param.p->type & SCTP_PARAM_ACTION_MASK) {
@@ -1976,11 +1978,41 @@ static sctp_ierror_t sctp_process_unk_param(const struct sctp_association *asoc,
 		/* Make an ERROR chunk, preparing enough room for
 		 * returning multiple unknown parameters.
 		 */
-		if (NULL == *errp)
-			*errp = sctp_make_op_error_space(asoc, chunk,
-					ntohs(chunk->chunk_hdr->length));
+		if (NULL == *errp) {
+			unsigned int len;
+
+			/* Reserver space for the worst possible case
+			 * at this time.  We count incomming chunk length
+			 * since error parameters carry the bad parameter
+			 * inself, plus have space for error headers for
+			 * the remaining number of parameters.
+			 */
+			len = ntohs(chunk->chunk_hdr->length);
+			len += sizeof(sctp_errhdr_t) * param_cnt;
+
+			/* We need to prevent amplification attacks that
+			 * result from sending 65K init chunks with all bad
+			 * params maliciously, so lets limit our error response
+			 * to 1 MTU worth of errors, but at least 1500 bytes
+			 * in case our pathmtu hasn't been updated yet.
+			 */
+			len = min(len, asoc ? asoc->pathmtu :
+						SCTP_DEFAULT_MAXSEGMENT);
+			*errp = sctp_make_op_error_space(asoc, chunk, len);
+		}
 
 		if (*errp) {
+			needed_bytes = sizeof(sctp_errhdr_t) +
+				       WORD_ROUND(ntohs(param.p->length));
+
+			if (skb_tailroom((*errp)->skb) < needed_bytes)
+				/*
+				 * If we're over our packet size here, don't add
+				 * the error, this is allowed by section 11.4 of
+				 * RFC 4960
+				 */
+				break;
+
 			sctp_init_cause(*errp, SCTP_ERROR_UNKNOWN_PARAM,
 					WORD_ROUND(ntohs(param.p->length)));
 			sctp_addto_chunk(*errp,
@@ -2013,7 +2045,8 @@ static sctp_ierror_t sctp_verify_param(const struct sctp_association *asoc,
 					union sctp_params param,
 					sctp_cid_t cid,
 					struct sctp_chunk *chunk,
-					struct sctp_chunk **err_chunk)
+					struct sctp_chunk **err_chunk,
+					unsigned int param_cnt)
 {
 	struct sctp_hmac_algo_param *hmacs;
 	int retval = SCTP_IERROR_NO_ERROR;
@@ -2119,7 +2152,8 @@ fallthrough:
 	default:
 		SCTP_DEBUG_PRINTK("Unrecognized param: %d for chunk %d.\n",
 				ntohs(param.p->type), cid);
-		retval = sctp_process_unk_param(asoc, param, chunk, err_chunk);
+		retval = sctp_process_unk_param(asoc, param, chunk, err_chunk,
+						param_cnt);
 		break;
 	}
 	return retval;
@@ -2135,6 +2169,7 @@ int sctp_verify_init(const struct sctp_association *asoc,
 	union sctp_params param;
 	int has_cookie = 0;
 	int result;
+	unsigned int param_cnt = 0;
 
 	/* Verify stream values are non-zero. */
 	if ((0 == peer_init->init_hdr.num_outbound_streams) ||
@@ -2150,6 +2185,7 @@ int sctp_verify_init(const struct sctp_association *asoc,
 
 		if (SCTP_PARAM_STATE_COOKIE == param.p->type)
 			has_cookie = 1;
+		param_cnt++;
 
 	} /* for (loop through all parameters) */
 
@@ -2173,7 +2209,8 @@ int sctp_verify_init(const struct sctp_association *asoc,
 	/* Verify all the variable length parameters */
 	sctp_walk_params(param, peer_init, init_hdr.params) {
 
-		result = sctp_verify_param(asoc, param, cid, chunk, errp);
+		result = sctp_verify_param(asoc, param, cid, chunk, errp,
+					   param_cnt);
 		switch (result) {
 		    case SCTP_IERROR_ABORT:
 		    case SCTP_IERROR_NOMEM:
@@ -2184,6 +2221,7 @@ int sctp_verify_init(const struct sctp_association *asoc,
 		    default:
 				break;
 		}
+		param_cnt--;
 
 	} /* for (loop through all parameters) */
 

WARNING: multiple messages have this Message-ID (diff)
From: Vlad Yasevich <vladislav.yasevich@hp.com>
To: Neil Horman <nhorman@tuxdriver.com>
Cc: sri@us.ibm.com, linux-sctp@vger.kernel.org, eteo@redhat.com,
	netdev@vger.kernel.org, davem@davemloft.net, security@kernel.org
Subject: Re: [PATCH]: sctp: Fix skb_over_panic resulting from multiple invalid parameter errors (CVE-2010-1173)
Date: Wed, 28 Apr 2010 14:27:11 -0400	[thread overview]
Message-ID: <4BD87DFF.6080502@hp.com> (raw)
In-Reply-To: <20100428181645.GD4818@hmsreliant.think-freely.org>

[-- Attachment #1: Type: text/plain, Size: 2614 bytes --]



Neil Horman wrote:
> On Wed, Apr 28, 2010 at 01:52:05PM -0400, Vlad Yasevich wrote:
>>
>> Vlad Yasevich wrote:
>>> Neil Horman wrote:
>>>> On Wed, Apr 28, 2010 at 10:00:37AM -0400, Vlad Yasevich wrote:
>>>>> I have this patch and a few others already queued.
>>>>>
>>>>> I was planning on sending these today for stable.
>>>>>
>>>>> Here is the full list of stable patches I have:
>>>>>
>>>>> sctp: Fix oops when sending queued ASCONF chunks
>>>>> sctp: fix to calc the INIT/INIT-ACK chunk length correctly is set
>>>>> sctp: per_cpu variables should be in bh_disabled section
>>>>> sctp: fix potential reference of a freed pointer
>>>>> sctp: avoid irq lock inversion while call sk->sk_data_ready()
>>>>>
>>>>> -vlad
>>>>>
>>>> Are you sure?  this oops looks _very_ simmilar to the INIT/INIT-ACK length
>>>> calculation oops described above, but is in fact different, and requires this
>>>> patch, from what I can see.  The right fix might be in the ASCONF chunk patch
>>>> you list above, but I don't see that in your tree at the moment, so I can't be
>>>> sure.
>>> As I said, I totally goofed when reading the description and I apologize.
>>> However, I do one comment regarding the patch.
>>>
>>> If the bad packet is REALLY long (I mean close to 65K IP limit), then
>>> we'll end up allocating a supper huge skb in this case and potentially exceed
>>> the IP length limitation.  Section 11.4 of rfc 4960 allows us to omit some
>>> errors and limit the size of the packet.
>>>
>>> I would recommend limiting this to MTU worth of potentiall errors.  This is
>>> on top of what the INIT-ACK is going to carry, so at most we'll sent 2 MTUs
>>> worth.  That's still a potential by amplification attack, but it's somewhat
>>> mitigated.
>>>
>>> Of course now we have to handle the case of checking for space before adding
>>> an error cause. :)
>>>
>> Hi Neil
>>
>> I am also not crazy about the pre-allocation scheme.  In the case where you have
>> say 100 parameters that are all 'skip' parameters, you'd end up pre-allocating a
>> huge buffer for absolutely nothing.
>>
> Would have been nice if you'd made your opinion known 4 hours ago when I was
> testing version 2 of this. :)
> 

sorry, fighting a head cold and need drugs to think clearly... ;)


>> This is another point toward a fixed error chunk size and let parameter
>> processing allocate it when it reaches a parameter that needs an error.
>>
> Hmm, ok, what would you say to a pathmtu sized chunk allocation in parameter
> processing that drops errors beyond its capacity
> Neil

Here is my quick take on this.  Haven't tested it at all.

-vlad

[-- Attachment #2: neil --]
[-- Type: text/plain, Size: 3987 bytes --]

diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c
index 0fd5b4c..74d8d21 100644
--- a/net/sctp/sm_make_chunk.c
+++ b/net/sctp/sm_make_chunk.c
@@ -1959,8 +1959,10 @@ static void sctp_process_ext_param(struct sctp_association *asoc,
 static sctp_ierror_t sctp_process_unk_param(const struct sctp_association *asoc,
 					    union sctp_params param,
 					    struct sctp_chunk *chunk,
-					    struct sctp_chunk **errp)
+					    struct sctp_chunk **errp,
+					    unsigned int param_cnt)
 {
+	unsigned int needed_bytes;
 	int retval = SCTP_IERROR_NO_ERROR;
 
 	switch (param.p->type & SCTP_PARAM_ACTION_MASK) {
@@ -1976,11 +1978,41 @@ static sctp_ierror_t sctp_process_unk_param(const struct sctp_association *asoc,
 		/* Make an ERROR chunk, preparing enough room for
 		 * returning multiple unknown parameters.
 		 */
-		if (NULL == *errp)
-			*errp = sctp_make_op_error_space(asoc, chunk,
-					ntohs(chunk->chunk_hdr->length));
+		if (NULL == *errp) {
+			unsigned int len;
+
+			/* Reserver space for the worst possible case
+			 * at this time.  We count incomming chunk length
+			 * since error parameters carry the bad parameter
+			 * inself, plus have space for error headers for
+			 * the remaining number of parameters.
+			 */
+			len = ntohs(chunk->chunk_hdr->length);
+			len += sizeof(sctp_errhdr_t) * param_cnt;
+
+			/* We need to prevent amplification attacks that
+			 * result from sending 65K init chunks with all bad
+			 * params maliciously, so lets limit our error response
+			 * to 1 MTU worth of errors, but at least 1500 bytes
+			 * in case our pathmtu hasn't been updated yet.
+			 */
+			len = min(len, asoc ? asoc->pathmtu :
+						SCTP_DEFAULT_MAXSEGMENT);
+			*errp = sctp_make_op_error_space(asoc, chunk, len);
+		}
 
 		if (*errp) {
+			needed_bytes = sizeof(sctp_errhdr_t) +
+				       WORD_ROUND(ntohs(param.p->length));
+
+			if (skb_tailroom((*errp)->skb) < needed_bytes)
+				/*
+				 * If we're over our packet size here, don't add
+				 * the error, this is allowed by section 11.4 of
+				 * RFC 4960
+				 */
+				break;
+
 			sctp_init_cause(*errp, SCTP_ERROR_UNKNOWN_PARAM,
 					WORD_ROUND(ntohs(param.p->length)));
 			sctp_addto_chunk(*errp,
@@ -2013,7 +2045,8 @@ static sctp_ierror_t sctp_verify_param(const struct sctp_association *asoc,
 					union sctp_params param,
 					sctp_cid_t cid,
 					struct sctp_chunk *chunk,
-					struct sctp_chunk **err_chunk)
+					struct sctp_chunk **err_chunk,
+					unsigned int param_cnt)
 {
 	struct sctp_hmac_algo_param *hmacs;
 	int retval = SCTP_IERROR_NO_ERROR;
@@ -2119,7 +2152,8 @@ fallthrough:
 	default:
 		SCTP_DEBUG_PRINTK("Unrecognized param: %d for chunk %d.\n",
 				ntohs(param.p->type), cid);
-		retval = sctp_process_unk_param(asoc, param, chunk, err_chunk);
+		retval = sctp_process_unk_param(asoc, param, chunk, err_chunk,
+						param_cnt);
 		break;
 	}
 	return retval;
@@ -2135,6 +2169,7 @@ int sctp_verify_init(const struct sctp_association *asoc,
 	union sctp_params param;
 	int has_cookie = 0;
 	int result;
+	unsigned int param_cnt = 0;
 
 	/* Verify stream values are non-zero. */
 	if ((0 == peer_init->init_hdr.num_outbound_streams) ||
@@ -2150,6 +2185,7 @@ int sctp_verify_init(const struct sctp_association *asoc,
 
 		if (SCTP_PARAM_STATE_COOKIE == param.p->type)
 			has_cookie = 1;
+		param_cnt++;
 
 	} /* for (loop through all parameters) */
 
@@ -2173,7 +2209,8 @@ int sctp_verify_init(const struct sctp_association *asoc,
 	/* Verify all the variable length parameters */
 	sctp_walk_params(param, peer_init, init_hdr.params) {
 
-		result = sctp_verify_param(asoc, param, cid, chunk, errp);
+		result = sctp_verify_param(asoc, param, cid, chunk, errp,
+					   param_cnt);
 		switch (result) {
 		    case SCTP_IERROR_ABORT:
 		    case SCTP_IERROR_NOMEM:
@@ -2184,6 +2221,7 @@ int sctp_verify_init(const struct sctp_association *asoc,
 		    default:
 				break;
 		}
+		param_cnt--;
 
 	} /* for (loop through all parameters) */
 

  reply	other threads:[~2010-04-28 18:27 UTC|newest]

Thread overview: 34+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-04-28 13:47 [PATCH]: sctp: Fix skb_over_panic resulting from multiple invalid Neil Horman
2010-04-28 13:47 ` [PATCH]: sctp: Fix skb_over_panic resulting from multiple invalid parameter errors (CVE-2010-1173) Neil Horman
2010-04-28 14:00 ` [PATCH]: sctp: Fix skb_over_panic resulting from multiple invalid Vlad Yasevich
2010-04-28 14:00   ` [PATCH]: sctp: Fix skb_over_panic resulting from multiple invalid parameter errors (CVE-2010-1173) Vlad Yasevich
2010-04-28 14:17   ` [PATCH]: sctp: Fix skb_over_panic resulting from multiple invalid Vlad Yasevich
2010-04-28 14:17     ` [PATCH]: sctp: Fix skb_over_panic resulting from multiple invalid parameter errors (CVE-2010-1173) Vlad Yasevich
2010-04-28 14:21   ` [PATCH]: sctp: Fix skb_over_panic resulting from multiple Neil Horman
2010-04-28 14:21     ` [PATCH]: sctp: Fix skb_over_panic resulting from multiple invalid parameter errors (CVE-2010-1173) Neil Horman
2010-04-28 14:37     ` [PATCH]: sctp: Fix skb_over_panic resulting from multiple invalid Vlad Yasevich
2010-04-28 14:37       ` [PATCH]: sctp: Fix skb_over_panic resulting from multiple invalid parameter errors (CVE-2010-1173) Vlad Yasevich
2010-04-28 17:47       ` [PATCH]: sctp: Fix skb_over_panic resulting from multiple Neil Horman
2010-04-28 17:47         ` [PATCH]: sctp: Fix skb_over_panic resulting from multiple invalid parameter errors (CVE-2010-1173) (v2) Neil Horman
2010-04-28 19:37         ` [PATCH]: sctp: Fix skb_over_panic resulting from multiple Neil Horman
2010-04-28 19:37           ` [PATCH]: sctp: Fix skb_over_panic resulting from multiple invalid parameter errors (CVE-2010-1173) (v3) Neil Horman
2010-04-28 20:16           ` [PATCH]: sctp: Fix skb_over_panic resulting from multiple invalid Vlad Yasevich
2010-04-28 20:16             ` [PATCH]: sctp: Fix skb_over_panic resulting from multiple invalid parameter errors (CVE-2010-1173) (v3) Vlad Yasevich
2010-04-28 20:30             ` [PATCH]: sctp: Fix skb_over_panic resulting from multiple Neil Horman
2010-04-28 20:30               ` [PATCH]: sctp: Fix skb_over_panic resulting from multiple invalid parameter errors (CVE-2010-1173) (v4) Neil Horman
2010-04-28 20:37               ` [PATCH]: sctp: Fix skb_over_panic resulting from multiple invalid Vlad Yasevich
2010-04-28 20:37                 ` [PATCH]: sctp: Fix skb_over_panic resulting from multiple invalid parameter errors (CVE-2010-1173) (v4) Vlad Yasevich
2010-04-28 21:23                 ` [PATCH]: sctp: Fix skb_over_panic resulting from multiple David Miller
2010-04-28 21:23                   ` [PATCH]: sctp: Fix skb_over_panic resulting from multiple invalid parameter errors (CVE-2010-1173) (v4) David Miller
2010-04-28 21:50                   ` [PATCH]: sctp: Fix skb_over_panic resulting from multiple Neil Horman
2010-04-28 21:50                     ` [PATCH]: sctp: Fix skb_over_panic resulting from multiple invalid parameter errors (CVE-2010-1173) (v4) Neil Horman
2010-04-29  0:25                     ` [PATCH]: sctp: Fix skb_over_panic resulting from multiple invalid Eugene Teo
2010-04-29  0:25                       ` [PATCH]: sctp: Fix skb_over_panic resulting from multiple invalid parameter errors (CVE-2010-1173) (v4) Eugene Teo
2010-04-28 17:52       ` [PATCH]: sctp: Fix skb_over_panic resulting from multiple invalid Vlad Yasevich
2010-04-28 17:52         ` [PATCH]: sctp: Fix skb_over_panic resulting from multiple invalid parameter errors (CVE-2010-1173) Vlad Yasevich
2010-04-28 18:16         ` [PATCH]: sctp: Fix skb_over_panic resulting from multiple Neil Horman
2010-04-28 18:16           ` [PATCH]: sctp: Fix skb_over_panic resulting from multiple invalid parameter errors (CVE-2010-1173) Neil Horman
2010-04-28 18:27           ` Vlad Yasevich [this message]
2010-04-28 18:27             ` Vlad Yasevich
2010-04-28 18:52             ` [PATCH]: sctp: Fix skb_over_panic resulting from multiple Neil Horman
2010-04-28 18:52               ` [PATCH]: sctp: Fix skb_over_panic resulting from multiple invalid parameter errors (CVE-2010-1173) Neil Horman

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=4BD87DFF.6080502@hp.com \
    --to=vladislav.yasevich@hp.com \
    --cc=davem@davemloft.net \
    --cc=eteo@redhat.com \
    --cc=linux-sctp@vger.kernel.org \
    --cc=netdev@vger.kernel.org \
    --cc=nhorman@tuxdriver.com \
    --cc=security@kernel.org \
    --cc=sri@us.ibm.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.