All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH net] sctp: check stream reset info len before making reconf chunk
@ 2017-11-13  5:39 ` Xin Long
  0 siblings, 0 replies; 16+ messages in thread
From: Xin Long @ 2017-11-13  5:39 UTC (permalink / raw)
  To: network dev, linux-sctp
  Cc: davem, Marcelo Ricardo Leitner, Neil Horman, Dmitry Vyukov, syzkaller

Now when resetting stream, if both in and out flags are set, the info
len can reach:
  sizeof(struct sctp_strreset_outreq) + SCTP_MAX_STREAM(65535) +
  sizeof(struct sctp_strreset_inreq)  + SCTP_MAX_STREAM(65535)
even without duplicated stream no, this value is far greater than the
chunk's max size.

_sctp_make_chunk doesn't do any check for this, which would cause the
skb it allocs is huge, syzbot even reported a crash due to this.

This patch is to check stream reset info len before making reconf
chunk and return NULL if the len exceeds chunk's capacity.

Fixes: cc16f00f6529 ("sctp: add support for generating stream reconf ssn reset request chunk")
Reported-by: Dmitry Vyukov <dvyukov@google.com>
Signed-off-by: Xin Long <lucien.xin@gmail.com>
---
 net/sctp/sm_make_chunk.c | 7 +++++--
 net/sctp/stream.c        | 8 +++++---
 2 files changed, 10 insertions(+), 5 deletions(-)

diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c
index 514465b..a21328a 100644
--- a/net/sctp/sm_make_chunk.c
+++ b/net/sctp/sm_make_chunk.c
@@ -3598,14 +3598,17 @@ struct sctp_chunk *sctp_make_strreset_req(
 	__u16 stream_len = stream_num * 2;
 	struct sctp_strreset_inreq inreq;
 	struct sctp_chunk *retval;
-	__u16 outlen, inlen;
+	int outlen, inlen;
 
 	outlen = (sizeof(outreq) + stream_len) * out;
 	inlen = (sizeof(inreq) + stream_len) * in;
 
+	if (outlen + inlen > SCTP_MAX_CHUNK_LEN - sizeof(struct sctp_chunkhdr))
+		return ERR_PTR(-EINVAL);
+
 	retval = sctp_make_reconf(asoc, outlen + inlen);
 	if (!retval)
-		return NULL;
+		return ERR_PTR(-ENOMEM);
 
 	if (outlen) {
 		outreq.param_hdr.type = SCTP_PARAM_RESET_OUT_REQUEST;
diff --git a/net/sctp/stream.c b/net/sctp/stream.c
index fa8371f..51a25bf 100644
--- a/net/sctp/stream.c
+++ b/net/sctp/stream.c
@@ -162,8 +162,8 @@ int sctp_send_reset_streams(struct sctp_association *asoc,
 
 	kfree(nstr_list);
 
-	if (!chunk) {
-		retval = -ENOMEM;
+	if (IS_ERR(chunk)) {
+		retval = PTR_ERR(chunk);
 		goto out;
 	}
 
@@ -482,8 +482,10 @@ struct sctp_chunk *sctp_process_strreset_inreq(
 	}
 
 	chunk = sctp_make_strreset_req(asoc, nums, str_p, 1, 0);
-	if (!chunk)
+	if (IS_ERR(chunk)) {
+		chunk = NULL;
 		goto out;
+	}
 
 	if (nums)
 		for (i = 0; i < nums; i++)
-- 
2.1.0

^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH net] sctp: check stream reset info len before making reconf chunk
@ 2017-11-13  5:39 ` Xin Long
  0 siblings, 0 replies; 16+ messages in thread
From: Xin Long @ 2017-11-13  5:39 UTC (permalink / raw)
  To: network dev, linux-sctp
  Cc: davem, Marcelo Ricardo Leitner, Neil Horman, Dmitry Vyukov, syzkaller

Now when resetting stream, if both in and out flags are set, the info
len can reach:
  sizeof(struct sctp_strreset_outreq) + SCTP_MAX_STREAM(65535) +
  sizeof(struct sctp_strreset_inreq)  + SCTP_MAX_STREAM(65535)
even without duplicated stream no, this value is far greater than the
chunk's max size.

_sctp_make_chunk doesn't do any check for this, which would cause the
skb it allocs is huge, syzbot even reported a crash due to this.

This patch is to check stream reset info len before making reconf
chunk and return NULL if the len exceeds chunk's capacity.

Fixes: cc16f00f6529 ("sctp: add support for generating stream reconf ssn reset request chunk")
Reported-by: Dmitry Vyukov <dvyukov@google.com>
Signed-off-by: Xin Long <lucien.xin@gmail.com>
---
 net/sctp/sm_make_chunk.c | 7 +++++--
 net/sctp/stream.c        | 8 +++++---
 2 files changed, 10 insertions(+), 5 deletions(-)

diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c
index 514465b..a21328a 100644
--- a/net/sctp/sm_make_chunk.c
+++ b/net/sctp/sm_make_chunk.c
@@ -3598,14 +3598,17 @@ struct sctp_chunk *sctp_make_strreset_req(
 	__u16 stream_len = stream_num * 2;
 	struct sctp_strreset_inreq inreq;
 	struct sctp_chunk *retval;
-	__u16 outlen, inlen;
+	int outlen, inlen;
 
 	outlen = (sizeof(outreq) + stream_len) * out;
 	inlen = (sizeof(inreq) + stream_len) * in;
 
+	if (outlen + inlen > SCTP_MAX_CHUNK_LEN - sizeof(struct sctp_chunkhdr))
+		return ERR_PTR(-EINVAL);
+
 	retval = sctp_make_reconf(asoc, outlen + inlen);
 	if (!retval)
-		return NULL;
+		return ERR_PTR(-ENOMEM);
 
 	if (outlen) {
 		outreq.param_hdr.type = SCTP_PARAM_RESET_OUT_REQUEST;
diff --git a/net/sctp/stream.c b/net/sctp/stream.c
index fa8371f..51a25bf 100644
--- a/net/sctp/stream.c
+++ b/net/sctp/stream.c
@@ -162,8 +162,8 @@ int sctp_send_reset_streams(struct sctp_association *asoc,
 
 	kfree(nstr_list);
 
-	if (!chunk) {
-		retval = -ENOMEM;
+	if (IS_ERR(chunk)) {
+		retval = PTR_ERR(chunk);
 		goto out;
 	}
 
@@ -482,8 +482,10 @@ struct sctp_chunk *sctp_process_strreset_inreq(
 	}
 
 	chunk = sctp_make_strreset_req(asoc, nums, str_p, 1, 0);
-	if (!chunk)
+	if (IS_ERR(chunk)) {
+		chunk = NULL;
 		goto out;
+	}
 
 	if (nums)
 		for (i = 0; i < nums; i++)
-- 
2.1.0


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* Re: [PATCH net] sctp: check stream reset info len before making reconf chunk
  2017-11-13  5:39 ` Xin Long
@ 2017-11-13 15:09   ` Neil Horman
  -1 siblings, 0 replies; 16+ messages in thread
From: Neil Horman @ 2017-11-13 15:09 UTC (permalink / raw)
  To: Xin Long
  Cc: network dev, linux-sctp, davem, Marcelo Ricardo Leitner,
	Dmitry Vyukov, syzkaller

On Mon, Nov 13, 2017 at 01:39:27PM +0800, Xin Long wrote:
> Now when resetting stream, if both in and out flags are set, the info
> len can reach:
>   sizeof(struct sctp_strreset_outreq) + SCTP_MAX_STREAM(65535) +
>   sizeof(struct sctp_strreset_inreq)  + SCTP_MAX_STREAM(65535)
> even without duplicated stream no, this value is far greater than the
> chunk's max size.
> 
> _sctp_make_chunk doesn't do any check for this, which would cause the
> skb it allocs is huge, syzbot even reported a crash due to this.
> 
> This patch is to check stream reset info len before making reconf
> chunk and return NULL if the len exceeds chunk's capacity.
> 
> Fixes: cc16f00f6529 ("sctp: add support for generating stream reconf ssn reset request chunk")
> Reported-by: Dmitry Vyukov <dvyukov@google.com>
> Signed-off-by: Xin Long <lucien.xin@gmail.com>
> ---
>  net/sctp/sm_make_chunk.c | 7 +++++--
>  net/sctp/stream.c        | 8 +++++---
>  2 files changed, 10 insertions(+), 5 deletions(-)
> 
> diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c
> index 514465b..a21328a 100644
> --- a/net/sctp/sm_make_chunk.c
> +++ b/net/sctp/sm_make_chunk.c
> @@ -3598,14 +3598,17 @@ struct sctp_chunk *sctp_make_strreset_req(
>  	__u16 stream_len = stream_num * 2;
>  	struct sctp_strreset_inreq inreq;
>  	struct sctp_chunk *retval;
> -	__u16 outlen, inlen;
> +	int outlen, inlen;
>  
>  	outlen = (sizeof(outreq) + stream_len) * out;
>  	inlen = (sizeof(inreq) + stream_len) * in;
>  
> +	if (outlen + inlen > SCTP_MAX_CHUNK_LEN - sizeof(struct sctp_chunkhdr))
> +		return ERR_PTR(-EINVAL);
> +
Why all the ERR_PTR manipulations here?  Just returning NULL, like the fuction
has been doing is sufficient to set ENOMEM at both call sites

Neil

>  	retval = sctp_make_reconf(asoc, outlen + inlen);
>  	if (!retval)
> -		return NULL;
> +		return ERR_PTR(-ENOMEM);
>  
>  	if (outlen) {
>  		outreq.param_hdr.type = SCTP_PARAM_RESET_OUT_REQUEST;
> diff --git a/net/sctp/stream.c b/net/sctp/stream.c
> index fa8371f..51a25bf 100644
> --- a/net/sctp/stream.c
> +++ b/net/sctp/stream.c
> @@ -162,8 +162,8 @@ int sctp_send_reset_streams(struct sctp_association *asoc,
>  
>  	kfree(nstr_list);
>  
> -	if (!chunk) {
> -		retval = -ENOMEM;
> +	if (IS_ERR(chunk)) {
> +		retval = PTR_ERR(chunk);
>  		goto out;
>  	}
>  
> @@ -482,8 +482,10 @@ struct sctp_chunk *sctp_process_strreset_inreq(
>  	}
>  
>  	chunk = sctp_make_strreset_req(asoc, nums, str_p, 1, 0);
> -	if (!chunk)
> +	if (IS_ERR(chunk)) {
> +		chunk = NULL;
>  		goto out;
> +	}
>  
>  	if (nums)
>  		for (i = 0; i < nums; i++)
> -- 
> 2.1.0
> 
> 

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH net] sctp: check stream reset info len before making reconf chunk
@ 2017-11-13 15:09   ` Neil Horman
  0 siblings, 0 replies; 16+ messages in thread
From: Neil Horman @ 2017-11-13 15:09 UTC (permalink / raw)
  To: Xin Long
  Cc: network dev, linux-sctp, davem, Marcelo Ricardo Leitner,
	Dmitry Vyukov, syzkaller

On Mon, Nov 13, 2017 at 01:39:27PM +0800, Xin Long wrote:
> Now when resetting stream, if both in and out flags are set, the info
> len can reach:
>   sizeof(struct sctp_strreset_outreq) + SCTP_MAX_STREAM(65535) +
>   sizeof(struct sctp_strreset_inreq)  + SCTP_MAX_STREAM(65535)
> even without duplicated stream no, this value is far greater than the
> chunk's max size.
> 
> _sctp_make_chunk doesn't do any check for this, which would cause the
> skb it allocs is huge, syzbot even reported a crash due to this.
> 
> This patch is to check stream reset info len before making reconf
> chunk and return NULL if the len exceeds chunk's capacity.
> 
> Fixes: cc16f00f6529 ("sctp: add support for generating stream reconf ssn reset request chunk")
> Reported-by: Dmitry Vyukov <dvyukov@google.com>
> Signed-off-by: Xin Long <lucien.xin@gmail.com>
> ---
>  net/sctp/sm_make_chunk.c | 7 +++++--
>  net/sctp/stream.c        | 8 +++++---
>  2 files changed, 10 insertions(+), 5 deletions(-)
> 
> diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c
> index 514465b..a21328a 100644
> --- a/net/sctp/sm_make_chunk.c
> +++ b/net/sctp/sm_make_chunk.c
> @@ -3598,14 +3598,17 @@ struct sctp_chunk *sctp_make_strreset_req(
>  	__u16 stream_len = stream_num * 2;
>  	struct sctp_strreset_inreq inreq;
>  	struct sctp_chunk *retval;
> -	__u16 outlen, inlen;
> +	int outlen, inlen;
>  
>  	outlen = (sizeof(outreq) + stream_len) * out;
>  	inlen = (sizeof(inreq) + stream_len) * in;
>  
> +	if (outlen + inlen > SCTP_MAX_CHUNK_LEN - sizeof(struct sctp_chunkhdr))
> +		return ERR_PTR(-EINVAL);
> +
Why all the ERR_PTR manipulations here?  Just returning NULL, like the fuction
has been doing is sufficient to set ENOMEM at both call sites

Neil

>  	retval = sctp_make_reconf(asoc, outlen + inlen);
>  	if (!retval)
> -		return NULL;
> +		return ERR_PTR(-ENOMEM);
>  
>  	if (outlen) {
>  		outreq.param_hdr.type = SCTP_PARAM_RESET_OUT_REQUEST;
> diff --git a/net/sctp/stream.c b/net/sctp/stream.c
> index fa8371f..51a25bf 100644
> --- a/net/sctp/stream.c
> +++ b/net/sctp/stream.c
> @@ -162,8 +162,8 @@ int sctp_send_reset_streams(struct sctp_association *asoc,
>  
>  	kfree(nstr_list);
>  
> -	if (!chunk) {
> -		retval = -ENOMEM;
> +	if (IS_ERR(chunk)) {
> +		retval = PTR_ERR(chunk);
>  		goto out;
>  	}
>  
> @@ -482,8 +482,10 @@ struct sctp_chunk *sctp_process_strreset_inreq(
>  	}
>  
>  	chunk = sctp_make_strreset_req(asoc, nums, str_p, 1, 0);
> -	if (!chunk)
> +	if (IS_ERR(chunk)) {
> +		chunk = NULL;
>  		goto out;
> +	}
>  
>  	if (nums)
>  		for (i = 0; i < nums; i++)
> -- 
> 2.1.0
> 
> 

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH net] sctp: check stream reset info len before making reconf chunk
  2017-11-13 15:09   ` Neil Horman
@ 2017-11-13 15:15     ` Xin Long
  -1 siblings, 0 replies; 16+ messages in thread
From: Xin Long @ 2017-11-13 15:15 UTC (permalink / raw)
  To: Neil Horman
  Cc: network dev, linux-sctp, davem, Marcelo Ricardo Leitner,
	Dmitry Vyukov, syzkaller

On Mon, Nov 13, 2017 at 11:09 PM, Neil Horman <nhorman@tuxdriver.com> wrote:
> On Mon, Nov 13, 2017 at 01:39:27PM +0800, Xin Long wrote:
>> Now when resetting stream, if both in and out flags are set, the info
>> len can reach:
>>   sizeof(struct sctp_strreset_outreq) + SCTP_MAX_STREAM(65535) +
>>   sizeof(struct sctp_strreset_inreq)  + SCTP_MAX_STREAM(65535)
>> even without duplicated stream no, this value is far greater than the
>> chunk's max size.
>>
>> _sctp_make_chunk doesn't do any check for this, which would cause the
>> skb it allocs is huge, syzbot even reported a crash due to this.
>>
>> This patch is to check stream reset info len before making reconf
>> chunk and return NULL if the len exceeds chunk's capacity.
>>
>> Fixes: cc16f00f6529 ("sctp: add support for generating stream reconf ssn reset request chunk")
>> Reported-by: Dmitry Vyukov <dvyukov@google.com>
>> Signed-off-by: Xin Long <lucien.xin@gmail.com>
>> ---
>>  net/sctp/sm_make_chunk.c | 7 +++++--
>>  net/sctp/stream.c        | 8 +++++---
>>  2 files changed, 10 insertions(+), 5 deletions(-)
>>
>> diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c
>> index 514465b..a21328a 100644
>> --- a/net/sctp/sm_make_chunk.c
>> +++ b/net/sctp/sm_make_chunk.c
>> @@ -3598,14 +3598,17 @@ struct sctp_chunk *sctp_make_strreset_req(
>>       __u16 stream_len = stream_num * 2;
>>       struct sctp_strreset_inreq inreq;
>>       struct sctp_chunk *retval;
>> -     __u16 outlen, inlen;
>> +     int outlen, inlen;
>>
>>       outlen = (sizeof(outreq) + stream_len) * out;
>>       inlen = (sizeof(inreq) + stream_len) * in;
>>
>> +     if (outlen + inlen > SCTP_MAX_CHUNK_LEN - sizeof(struct sctp_chunkhdr))
>> +             return ERR_PTR(-EINVAL);
>> +
> Why all the ERR_PTR manipulations here?  Just returning NULL, like the fuction
> has been doing is sufficient to set ENOMEM at both call sites
I don't like ERR_PTR handling here either,
But it shouldn't be ENOMEM, should it ?

It may confuse users, but I'm also ok to let it just return
ENOMEM as you wish. wdyt ?

>
> Neil
>
>>       retval = sctp_make_reconf(asoc, outlen + inlen);
>>       if (!retval)
>> -             return NULL;
>> +             return ERR_PTR(-ENOMEM);
>>
>>       if (outlen) {
>>               outreq.param_hdr.type = SCTP_PARAM_RESET_OUT_REQUEST;
>> diff --git a/net/sctp/stream.c b/net/sctp/stream.c
>> index fa8371f..51a25bf 100644
>> --- a/net/sctp/stream.c
>> +++ b/net/sctp/stream.c
>> @@ -162,8 +162,8 @@ int sctp_send_reset_streams(struct sctp_association *asoc,
>>
>>       kfree(nstr_list);
>>
>> -     if (!chunk) {
>> -             retval = -ENOMEM;
>> +     if (IS_ERR(chunk)) {
>> +             retval = PTR_ERR(chunk);
>>               goto out;
>>       }
>>
>> @@ -482,8 +482,10 @@ struct sctp_chunk *sctp_process_strreset_inreq(
>>       }
>>
>>       chunk = sctp_make_strreset_req(asoc, nums, str_p, 1, 0);
>> -     if (!chunk)
>> +     if (IS_ERR(chunk)) {
>> +             chunk = NULL;
>>               goto out;
>> +     }
>>
>>       if (nums)
>>               for (i = 0; i < nums; i++)
>> --
>> 2.1.0
>>
>>

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH net] sctp: check stream reset info len before making reconf chunk
@ 2017-11-13 15:15     ` Xin Long
  0 siblings, 0 replies; 16+ messages in thread
From: Xin Long @ 2017-11-13 15:15 UTC (permalink / raw)
  To: Neil Horman
  Cc: network dev, linux-sctp, davem, Marcelo Ricardo Leitner,
	Dmitry Vyukov, syzkaller

On Mon, Nov 13, 2017 at 11:09 PM, Neil Horman <nhorman@tuxdriver.com> wrote:
> On Mon, Nov 13, 2017 at 01:39:27PM +0800, Xin Long wrote:
>> Now when resetting stream, if both in and out flags are set, the info
>> len can reach:
>>   sizeof(struct sctp_strreset_outreq) + SCTP_MAX_STREAM(65535) +
>>   sizeof(struct sctp_strreset_inreq)  + SCTP_MAX_STREAM(65535)
>> even without duplicated stream no, this value is far greater than the
>> chunk's max size.
>>
>> _sctp_make_chunk doesn't do any check for this, which would cause the
>> skb it allocs is huge, syzbot even reported a crash due to this.
>>
>> This patch is to check stream reset info len before making reconf
>> chunk and return NULL if the len exceeds chunk's capacity.
>>
>> Fixes: cc16f00f6529 ("sctp: add support for generating stream reconf ssn reset request chunk")
>> Reported-by: Dmitry Vyukov <dvyukov@google.com>
>> Signed-off-by: Xin Long <lucien.xin@gmail.com>
>> ---
>>  net/sctp/sm_make_chunk.c | 7 +++++--
>>  net/sctp/stream.c        | 8 +++++---
>>  2 files changed, 10 insertions(+), 5 deletions(-)
>>
>> diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c
>> index 514465b..a21328a 100644
>> --- a/net/sctp/sm_make_chunk.c
>> +++ b/net/sctp/sm_make_chunk.c
>> @@ -3598,14 +3598,17 @@ struct sctp_chunk *sctp_make_strreset_req(
>>       __u16 stream_len = stream_num * 2;
>>       struct sctp_strreset_inreq inreq;
>>       struct sctp_chunk *retval;
>> -     __u16 outlen, inlen;
>> +     int outlen, inlen;
>>
>>       outlen = (sizeof(outreq) + stream_len) * out;
>>       inlen = (sizeof(inreq) + stream_len) * in;
>>
>> +     if (outlen + inlen > SCTP_MAX_CHUNK_LEN - sizeof(struct sctp_chunkhdr))
>> +             return ERR_PTR(-EINVAL);
>> +
> Why all the ERR_PTR manipulations here?  Just returning NULL, like the fuction
> has been doing is sufficient to set ENOMEM at both call sites
I don't like ERR_PTR handling here either,
But it shouldn't be ENOMEM, should it ?

It may confuse users, but I'm also ok to let it just return
ENOMEM as you wish. wdyt ?

>
> Neil
>
>>       retval = sctp_make_reconf(asoc, outlen + inlen);
>>       if (!retval)
>> -             return NULL;
>> +             return ERR_PTR(-ENOMEM);
>>
>>       if (outlen) {
>>               outreq.param_hdr.type = SCTP_PARAM_RESET_OUT_REQUEST;
>> diff --git a/net/sctp/stream.c b/net/sctp/stream.c
>> index fa8371f..51a25bf 100644
>> --- a/net/sctp/stream.c
>> +++ b/net/sctp/stream.c
>> @@ -162,8 +162,8 @@ int sctp_send_reset_streams(struct sctp_association *asoc,
>>
>>       kfree(nstr_list);
>>
>> -     if (!chunk) {
>> -             retval = -ENOMEM;
>> +     if (IS_ERR(chunk)) {
>> +             retval = PTR_ERR(chunk);
>>               goto out;
>>       }
>>
>> @@ -482,8 +482,10 @@ struct sctp_chunk *sctp_process_strreset_inreq(
>>       }
>>
>>       chunk = sctp_make_strreset_req(asoc, nums, str_p, 1, 0);
>> -     if (!chunk)
>> +     if (IS_ERR(chunk)) {
>> +             chunk = NULL;
>>               goto out;
>> +     }
>>
>>       if (nums)
>>               for (i = 0; i < nums; i++)
>> --
>> 2.1.0
>>
>>

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH net] sctp: check stream reset info len before making reconf chunk
  2017-11-13 15:15     ` Xin Long
@ 2017-11-13 19:54       ` Marcelo Ricardo Leitner
  -1 siblings, 0 replies; 16+ messages in thread
From: Marcelo Ricardo Leitner @ 2017-11-13 19:54 UTC (permalink / raw)
  To: Xin Long
  Cc: Neil Horman, network dev, linux-sctp, davem, Dmitry Vyukov, syzkaller

On Mon, Nov 13, 2017 at 11:15:40PM +0800, Xin Long wrote:
> On Mon, Nov 13, 2017 at 11:09 PM, Neil Horman <nhorman@tuxdriver.com> wrote:
> > On Mon, Nov 13, 2017 at 01:39:27PM +0800, Xin Long wrote:
> >> Now when resetting stream, if both in and out flags are set, the info
> >> len can reach:
> >>   sizeof(struct sctp_strreset_outreq) + SCTP_MAX_STREAM(65535) +
> >>   sizeof(struct sctp_strreset_inreq)  + SCTP_MAX_STREAM(65535)
> >> even without duplicated stream no, this value is far greater than the
> >> chunk's max size.
> >>
> >> _sctp_make_chunk doesn't do any check for this, which would cause the
> >> skb it allocs is huge, syzbot even reported a crash due to this.
> >>
> >> This patch is to check stream reset info len before making reconf
> >> chunk and return NULL if the len exceeds chunk's capacity.
> >>
> >> Fixes: cc16f00f6529 ("sctp: add support for generating stream reconf ssn reset request chunk")
> >> Reported-by: Dmitry Vyukov <dvyukov@google.com>
> >> Signed-off-by: Xin Long <lucien.xin@gmail.com>
> >> ---
> >>  net/sctp/sm_make_chunk.c | 7 +++++--
> >>  net/sctp/stream.c        | 8 +++++---
> >>  2 files changed, 10 insertions(+), 5 deletions(-)
> >>
> >> diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c
> >> index 514465b..a21328a 100644
> >> --- a/net/sctp/sm_make_chunk.c
> >> +++ b/net/sctp/sm_make_chunk.c
> >> @@ -3598,14 +3598,17 @@ struct sctp_chunk *sctp_make_strreset_req(
> >>       __u16 stream_len = stream_num * 2;

Unrelated, but.. won't stream_len overflow if stream_num >= 32768?
When called form sctp_send_reset_streams() I don't see anything
restricting it to such range.

> >>       struct sctp_strreset_inreq inreq;
> >>       struct sctp_chunk *retval;
> >> -     __u16 outlen, inlen;
> >> +     int outlen, inlen;
> >>
> >>       outlen = (sizeof(outreq) + stream_len) * out;
> >>       inlen = (sizeof(inreq) + stream_len) * in;
> >>
> >> +     if (outlen + inlen > SCTP_MAX_CHUNK_LEN - sizeof(struct sctp_chunkhdr))
> >> +             return ERR_PTR(-EINVAL);
> >> +
> > Why all the ERR_PTR manipulations here?  Just returning NULL, like the fuction
> > has been doing is sufficient to set ENOMEM at both call sites
> I don't like ERR_PTR handling here either,
> But it shouldn't be ENOMEM, should it ?
> 
> It may confuse users, but I'm also ok to let it just return
> ENOMEM as you wish. wdyt ?

Returning ENOMEM in the above error can be misleading. It's not that
we cannot allocate it, it's that it won't fit the packet no matter how
much memory we add to the system.

  Marcelo

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH net] sctp: check stream reset info len before making reconf chunk
@ 2017-11-13 19:54       ` Marcelo Ricardo Leitner
  0 siblings, 0 replies; 16+ messages in thread
From: Marcelo Ricardo Leitner @ 2017-11-13 19:54 UTC (permalink / raw)
  To: Xin Long
  Cc: Neil Horman, network dev, linux-sctp, davem, Dmitry Vyukov, syzkaller

On Mon, Nov 13, 2017 at 11:15:40PM +0800, Xin Long wrote:
> On Mon, Nov 13, 2017 at 11:09 PM, Neil Horman <nhorman@tuxdriver.com> wrote:
> > On Mon, Nov 13, 2017 at 01:39:27PM +0800, Xin Long wrote:
> >> Now when resetting stream, if both in and out flags are set, the info
> >> len can reach:
> >>   sizeof(struct sctp_strreset_outreq) + SCTP_MAX_STREAM(65535) +
> >>   sizeof(struct sctp_strreset_inreq)  + SCTP_MAX_STREAM(65535)
> >> even without duplicated stream no, this value is far greater than the
> >> chunk's max size.
> >>
> >> _sctp_make_chunk doesn't do any check for this, which would cause the
> >> skb it allocs is huge, syzbot even reported a crash due to this.
> >>
> >> This patch is to check stream reset info len before making reconf
> >> chunk and return NULL if the len exceeds chunk's capacity.
> >>
> >> Fixes: cc16f00f6529 ("sctp: add support for generating stream reconf ssn reset request chunk")
> >> Reported-by: Dmitry Vyukov <dvyukov@google.com>
> >> Signed-off-by: Xin Long <lucien.xin@gmail.com>
> >> ---
> >>  net/sctp/sm_make_chunk.c | 7 +++++--
> >>  net/sctp/stream.c        | 8 +++++---
> >>  2 files changed, 10 insertions(+), 5 deletions(-)
> >>
> >> diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c
> >> index 514465b..a21328a 100644
> >> --- a/net/sctp/sm_make_chunk.c
> >> +++ b/net/sctp/sm_make_chunk.c
> >> @@ -3598,14 +3598,17 @@ struct sctp_chunk *sctp_make_strreset_req(
> >>       __u16 stream_len = stream_num * 2;

Unrelated, but.. won't stream_len overflow if stream_num >= 32768?
When called form sctp_send_reset_streams() I don't see anything
restricting it to such range.

> >>       struct sctp_strreset_inreq inreq;
> >>       struct sctp_chunk *retval;
> >> -     __u16 outlen, inlen;
> >> +     int outlen, inlen;
> >>
> >>       outlen = (sizeof(outreq) + stream_len) * out;
> >>       inlen = (sizeof(inreq) + stream_len) * in;
> >>
> >> +     if (outlen + inlen > SCTP_MAX_CHUNK_LEN - sizeof(struct sctp_chunkhdr))
> >> +             return ERR_PTR(-EINVAL);
> >> +
> > Why all the ERR_PTR manipulations here?  Just returning NULL, like the fuction
> > has been doing is sufficient to set ENOMEM at both call sites
> I don't like ERR_PTR handling here either,
> But it shouldn't be ENOMEM, should it ?
> 
> It may confuse users, but I'm also ok to let it just return
> ENOMEM as you wish. wdyt ?

Returning ENOMEM in the above error can be misleading. It's not that
we cannot allocate it, it's that it won't fit the packet no matter how
much memory we add to the system.

  Marcelo

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH net] sctp: check stream reset info len before making reconf chunk
  2017-11-13 19:54       ` Marcelo Ricardo Leitner
@ 2017-11-14  8:27         ` Xin Long
  -1 siblings, 0 replies; 16+ messages in thread
From: Xin Long @ 2017-11-14  8:27 UTC (permalink / raw)
  To: Marcelo Ricardo Leitner
  Cc: Neil Horman, network dev, linux-sctp, davem, Dmitry Vyukov, syzkaller

On Tue, Nov 14, 2017 at 3:54 AM, Marcelo Ricardo Leitner
<marcelo.leitner@gmail.com> wrote:
> On Mon, Nov 13, 2017 at 11:15:40PM +0800, Xin Long wrote:
>> On Mon, Nov 13, 2017 at 11:09 PM, Neil Horman <nhorman@tuxdriver.com> wrote:
>> > On Mon, Nov 13, 2017 at 01:39:27PM +0800, Xin Long wrote:
>> >> Now when resetting stream, if both in and out flags are set, the info
>> >> len can reach:
>> >>   sizeof(struct sctp_strreset_outreq) + SCTP_MAX_STREAM(65535) +
>> >>   sizeof(struct sctp_strreset_inreq)  + SCTP_MAX_STREAM(65535)
>> >> even without duplicated stream no, this value is far greater than the
>> >> chunk's max size.
>> >>
>> >> _sctp_make_chunk doesn't do any check for this, which would cause the
>> >> skb it allocs is huge, syzbot even reported a crash due to this.
>> >>
>> >> This patch is to check stream reset info len before making reconf
>> >> chunk and return NULL if the len exceeds chunk's capacity.
>> >>
>> >> Fixes: cc16f00f6529 ("sctp: add support for generating stream reconf ssn reset request chunk")
>> >> Reported-by: Dmitry Vyukov <dvyukov@google.com>
>> >> Signed-off-by: Xin Long <lucien.xin@gmail.com>
>> >> ---
>> >>  net/sctp/sm_make_chunk.c | 7 +++++--
>> >>  net/sctp/stream.c        | 8 +++++---
>> >>  2 files changed, 10 insertions(+), 5 deletions(-)
>> >>
>> >> diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c
>> >> index 514465b..a21328a 100644
>> >> --- a/net/sctp/sm_make_chunk.c
>> >> +++ b/net/sctp/sm_make_chunk.c
>> >> @@ -3598,14 +3598,17 @@ struct sctp_chunk *sctp_make_strreset_req(
>> >>       __u16 stream_len = stream_num * 2;
>
> Unrelated, but.. won't stream_len overflow if stream_num >= 32768?
> When called form sctp_send_reset_streams() I don't see anything
> restricting it to such range.
right.

>
>> >>       struct sctp_strreset_inreq inreq;
>> >>       struct sctp_chunk *retval;
>> >> -     __u16 outlen, inlen;
>> >> +     int outlen, inlen;
>> >>
>> >>       outlen = (sizeof(outreq) + stream_len) * out;
>> >>       inlen = (sizeof(inreq) + stream_len) * in;
>> >>
>> >> +     if (outlen + inlen > SCTP_MAX_CHUNK_LEN - sizeof(struct sctp_chunkhdr))
>> >> +             return ERR_PTR(-EINVAL);
>> >> +
>> > Why all the ERR_PTR manipulations here?  Just returning NULL, like the fuction
>> > has been doing is sufficient to set ENOMEM at both call sites
>> I don't like ERR_PTR handling here either,
>> But it shouldn't be ENOMEM, should it ?
>>
>> It may confuse users, but I'm also ok to let it just return
>> ENOMEM as you wish. wdyt ?
>
> Returning ENOMEM in the above error can be misleading. It's not that
> we cannot allocate it, it's that it won't fit the packet no matter how
> much memory we add to the system.
right.

let's move the check into sctp_send_reset_streams()

I believe this one fixes them both:
@@ -139,15 +139,31 @@ int sctp_send_reset_streams(struct sctp_association *asoc,

        str_nums = params->srs_number_streams;
        str_list = params->srs_stream_list;
-       if (out && str_nums)
-               for (i = 0; i < str_nums; i++)
-                       if (str_list[i] >= stream->outcnt)
-                               goto out;
+       if (str_nums) {
+               int param_len = 0;

-       if (in && str_nums)
-               for (i = 0; i < str_nums; i++)
-                       if (str_list[i] >= stream->incnt)
-                               goto out;
+               if (out) {
+                       for (i = 0; i < str_nums; i++)
+                               if (str_list[i] >= stream->outcnt)
+                                       goto out;
+
+                       param_len = str_nums * 2 +
+                                   sizeof(struct sctp_strreset_outreq);
+               }
+
+               if (in) {
+                       for (i = 0; i < str_nums; i++)
+                               if (str_list[i] >= stream->incnt)
+                                       goto out;
+
+                       param_len += str_nums * 2 +
+                                    sizeof(struct sctp_strreset_inreq);
+               }
+
+               if (param_len > SCTP_MAX_CHUNK_LEN -
+                               sizeof(struct sctp_reconf_chunk))
+                       goto out;
+       }


and int this fix,  it's good to do all checks only when str_nums !=0.

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH net] sctp: check stream reset info len before making reconf chunk
@ 2017-11-14  8:27         ` Xin Long
  0 siblings, 0 replies; 16+ messages in thread
From: Xin Long @ 2017-11-14  8:27 UTC (permalink / raw)
  To: Marcelo Ricardo Leitner
  Cc: Neil Horman, network dev, linux-sctp, davem, Dmitry Vyukov, syzkaller

On Tue, Nov 14, 2017 at 3:54 AM, Marcelo Ricardo Leitner
<marcelo.leitner@gmail.com> wrote:
> On Mon, Nov 13, 2017 at 11:15:40PM +0800, Xin Long wrote:
>> On Mon, Nov 13, 2017 at 11:09 PM, Neil Horman <nhorman@tuxdriver.com> wrote:
>> > On Mon, Nov 13, 2017 at 01:39:27PM +0800, Xin Long wrote:
>> >> Now when resetting stream, if both in and out flags are set, the info
>> >> len can reach:
>> >>   sizeof(struct sctp_strreset_outreq) + SCTP_MAX_STREAM(65535) +
>> >>   sizeof(struct sctp_strreset_inreq)  + SCTP_MAX_STREAM(65535)
>> >> even without duplicated stream no, this value is far greater than the
>> >> chunk's max size.
>> >>
>> >> _sctp_make_chunk doesn't do any check for this, which would cause the
>> >> skb it allocs is huge, syzbot even reported a crash due to this.
>> >>
>> >> This patch is to check stream reset info len before making reconf
>> >> chunk and return NULL if the len exceeds chunk's capacity.
>> >>
>> >> Fixes: cc16f00f6529 ("sctp: add support for generating stream reconf ssn reset request chunk")
>> >> Reported-by: Dmitry Vyukov <dvyukov@google.com>
>> >> Signed-off-by: Xin Long <lucien.xin@gmail.com>
>> >> ---
>> >>  net/sctp/sm_make_chunk.c | 7 +++++--
>> >>  net/sctp/stream.c        | 8 +++++---
>> >>  2 files changed, 10 insertions(+), 5 deletions(-)
>> >>
>> >> diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c
>> >> index 514465b..a21328a 100644
>> >> --- a/net/sctp/sm_make_chunk.c
>> >> +++ b/net/sctp/sm_make_chunk.c
>> >> @@ -3598,14 +3598,17 @@ struct sctp_chunk *sctp_make_strreset_req(
>> >>       __u16 stream_len = stream_num * 2;
>
> Unrelated, but.. won't stream_len overflow if stream_num >= 32768?
> When called form sctp_send_reset_streams() I don't see anything
> restricting it to such range.
right.

>
>> >>       struct sctp_strreset_inreq inreq;
>> >>       struct sctp_chunk *retval;
>> >> -     __u16 outlen, inlen;
>> >> +     int outlen, inlen;
>> >>
>> >>       outlen = (sizeof(outreq) + stream_len) * out;
>> >>       inlen = (sizeof(inreq) + stream_len) * in;
>> >>
>> >> +     if (outlen + inlen > SCTP_MAX_CHUNK_LEN - sizeof(struct sctp_chunkhdr))
>> >> +             return ERR_PTR(-EINVAL);
>> >> +
>> > Why all the ERR_PTR manipulations here?  Just returning NULL, like the fuction
>> > has been doing is sufficient to set ENOMEM at both call sites
>> I don't like ERR_PTR handling here either,
>> But it shouldn't be ENOMEM, should it ?
>>
>> It may confuse users, but I'm also ok to let it just return
>> ENOMEM as you wish. wdyt ?
>
> Returning ENOMEM in the above error can be misleading. It's not that
> we cannot allocate it, it's that it won't fit the packet no matter how
> much memory we add to the system.
right.

let's move the check into sctp_send_reset_streams()

I believe this one fixes them both:
@@ -139,15 +139,31 @@ int sctp_send_reset_streams(struct sctp_association *asoc,

        str_nums = params->srs_number_streams;
        str_list = params->srs_stream_list;
-       if (out && str_nums)
-               for (i = 0; i < str_nums; i++)
-                       if (str_list[i] >= stream->outcnt)
-                               goto out;
+       if (str_nums) {
+               int param_len = 0;

-       if (in && str_nums)
-               for (i = 0; i < str_nums; i++)
-                       if (str_list[i] >= stream->incnt)
-                               goto out;
+               if (out) {
+                       for (i = 0; i < str_nums; i++)
+                               if (str_list[i] >= stream->outcnt)
+                                       goto out;
+
+                       param_len = str_nums * 2 +
+                                   sizeof(struct sctp_strreset_outreq);
+               }
+
+               if (in) {
+                       for (i = 0; i < str_nums; i++)
+                               if (str_list[i] >= stream->incnt)
+                                       goto out;
+
+                       param_len += str_nums * 2 +
+                                    sizeof(struct sctp_strreset_inreq);
+               }
+
+               if (param_len > SCTP_MAX_CHUNK_LEN -
+                               sizeof(struct sctp_reconf_chunk))
+                       goto out;
+       }


and int this fix,  it's good to do all checks only when str_nums !=0.

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH net] sctp: check stream reset info len before making reconf chunk
  2017-11-13 15:15     ` Xin Long
@ 2017-11-14 12:46       ` Neil Horman
  -1 siblings, 0 replies; 16+ messages in thread
From: Neil Horman @ 2017-11-14 12:46 UTC (permalink / raw)
  To: Xin Long
  Cc: network dev, linux-sctp, davem, Marcelo Ricardo Leitner,
	Dmitry Vyukov, syzkaller

On Mon, Nov 13, 2017 at 11:15:40PM +0800, Xin Long wrote:
> On Mon, Nov 13, 2017 at 11:09 PM, Neil Horman <nhorman@tuxdriver.com> wrote:
> > On Mon, Nov 13, 2017 at 01:39:27PM +0800, Xin Long wrote:
> >> Now when resetting stream, if both in and out flags are set, the info
> >> len can reach:
> >>   sizeof(struct sctp_strreset_outreq) + SCTP_MAX_STREAM(65535) +
> >>   sizeof(struct sctp_strreset_inreq)  + SCTP_MAX_STREAM(65535)
> >> even without duplicated stream no, this value is far greater than the
> >> chunk's max size.
> >>
> >> _sctp_make_chunk doesn't do any check for this, which would cause the
> >> skb it allocs is huge, syzbot even reported a crash due to this.
> >>
> >> This patch is to check stream reset info len before making reconf
> >> chunk and return NULL if the len exceeds chunk's capacity.
> >>
> >> Fixes: cc16f00f6529 ("sctp: add support for generating stream reconf ssn reset request chunk")
> >> Reported-by: Dmitry Vyukov <dvyukov@google.com>
> >> Signed-off-by: Xin Long <lucien.xin@gmail.com>
> >> ---
> >>  net/sctp/sm_make_chunk.c | 7 +++++--
> >>  net/sctp/stream.c        | 8 +++++---
> >>  2 files changed, 10 insertions(+), 5 deletions(-)
> >>
> >> diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c
> >> index 514465b..a21328a 100644
> >> --- a/net/sctp/sm_make_chunk.c
> >> +++ b/net/sctp/sm_make_chunk.c
> >> @@ -3598,14 +3598,17 @@ struct sctp_chunk *sctp_make_strreset_req(
> >>       __u16 stream_len = stream_num * 2;
> >>       struct sctp_strreset_inreq inreq;
> >>       struct sctp_chunk *retval;
> >> -     __u16 outlen, inlen;
> >> +     int outlen, inlen;
> >>
> >>       outlen = (sizeof(outreq) + stream_len) * out;
> >>       inlen = (sizeof(inreq) + stream_len) * in;
> >>
> >> +     if (outlen + inlen > SCTP_MAX_CHUNK_LEN - sizeof(struct sctp_chunkhdr))
> >> +             return ERR_PTR(-EINVAL);
> >> +
> > Why all the ERR_PTR manipulations here?  Just returning NULL, like the fuction
> > has been doing is sufficient to set ENOMEM at both call sites
> I don't like ERR_PTR handling here either,
> But it shouldn't be ENOMEM, should it ?
> 
> It may confuse users, but I'm also ok to let it just return
> ENOMEM as you wish. wdyt ?
> 
I'm ok with ENOMEM.  If someone tries to reconf the streams with huge values,
ENOMEM makes sense to me
Neil

> >
> > Neil
> >
> >>       retval = sctp_make_reconf(asoc, outlen + inlen);
> >>       if (!retval)
> >> -             return NULL;
> >> +             return ERR_PTR(-ENOMEM);
> >>
> >>       if (outlen) {
> >>               outreq.param_hdr.type = SCTP_PARAM_RESET_OUT_REQUEST;
> >> diff --git a/net/sctp/stream.c b/net/sctp/stream.c
> >> index fa8371f..51a25bf 100644
> >> --- a/net/sctp/stream.c
> >> +++ b/net/sctp/stream.c
> >> @@ -162,8 +162,8 @@ int sctp_send_reset_streams(struct sctp_association *asoc,
> >>
> >>       kfree(nstr_list);
> >>
> >> -     if (!chunk) {
> >> -             retval = -ENOMEM;
> >> +     if (IS_ERR(chunk)) {
> >> +             retval = PTR_ERR(chunk);
> >>               goto out;
> >>       }
> >>
> >> @@ -482,8 +482,10 @@ struct sctp_chunk *sctp_process_strreset_inreq(
> >>       }
> >>
> >>       chunk = sctp_make_strreset_req(asoc, nums, str_p, 1, 0);
> >> -     if (!chunk)
> >> +     if (IS_ERR(chunk)) {
> >> +             chunk = NULL;
> >>               goto out;
> >> +     }
> >>
> >>       if (nums)
> >>               for (i = 0; i < nums; i++)
> >> --
> >> 2.1.0
> >>
> >>
> 

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH net] sctp: check stream reset info len before making reconf chunk
@ 2017-11-14 12:46       ` Neil Horman
  0 siblings, 0 replies; 16+ messages in thread
From: Neil Horman @ 2017-11-14 12:46 UTC (permalink / raw)
  To: Xin Long
  Cc: network dev, linux-sctp, davem, Marcelo Ricardo Leitner,
	Dmitry Vyukov, syzkaller

On Mon, Nov 13, 2017 at 11:15:40PM +0800, Xin Long wrote:
> On Mon, Nov 13, 2017 at 11:09 PM, Neil Horman <nhorman@tuxdriver.com> wrote:
> > On Mon, Nov 13, 2017 at 01:39:27PM +0800, Xin Long wrote:
> >> Now when resetting stream, if both in and out flags are set, the info
> >> len can reach:
> >>   sizeof(struct sctp_strreset_outreq) + SCTP_MAX_STREAM(65535) +
> >>   sizeof(struct sctp_strreset_inreq)  + SCTP_MAX_STREAM(65535)
> >> even without duplicated stream no, this value is far greater than the
> >> chunk's max size.
> >>
> >> _sctp_make_chunk doesn't do any check for this, which would cause the
> >> skb it allocs is huge, syzbot even reported a crash due to this.
> >>
> >> This patch is to check stream reset info len before making reconf
> >> chunk and return NULL if the len exceeds chunk's capacity.
> >>
> >> Fixes: cc16f00f6529 ("sctp: add support for generating stream reconf ssn reset request chunk")
> >> Reported-by: Dmitry Vyukov <dvyukov@google.com>
> >> Signed-off-by: Xin Long <lucien.xin@gmail.com>
> >> ---
> >>  net/sctp/sm_make_chunk.c | 7 +++++--
> >>  net/sctp/stream.c        | 8 +++++---
> >>  2 files changed, 10 insertions(+), 5 deletions(-)
> >>
> >> diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c
> >> index 514465b..a21328a 100644
> >> --- a/net/sctp/sm_make_chunk.c
> >> +++ b/net/sctp/sm_make_chunk.c
> >> @@ -3598,14 +3598,17 @@ struct sctp_chunk *sctp_make_strreset_req(
> >>       __u16 stream_len = stream_num * 2;
> >>       struct sctp_strreset_inreq inreq;
> >>       struct sctp_chunk *retval;
> >> -     __u16 outlen, inlen;
> >> +     int outlen, inlen;
> >>
> >>       outlen = (sizeof(outreq) + stream_len) * out;
> >>       inlen = (sizeof(inreq) + stream_len) * in;
> >>
> >> +     if (outlen + inlen > SCTP_MAX_CHUNK_LEN - sizeof(struct sctp_chunkhdr))
> >> +             return ERR_PTR(-EINVAL);
> >> +
> > Why all the ERR_PTR manipulations here?  Just returning NULL, like the fuction
> > has been doing is sufficient to set ENOMEM at both call sites
> I don't like ERR_PTR handling here either,
> But it shouldn't be ENOMEM, should it ?
> 
> It may confuse users, but I'm also ok to let it just return
> ENOMEM as you wish. wdyt ?
> 
I'm ok with ENOMEM.  If someone tries to reconf the streams with huge values,
ENOMEM makes sense to me
Neil

> >
> > Neil
> >
> >>       retval = sctp_make_reconf(asoc, outlen + inlen);
> >>       if (!retval)
> >> -             return NULL;
> >> +             return ERR_PTR(-ENOMEM);
> >>
> >>       if (outlen) {
> >>               outreq.param_hdr.type = SCTP_PARAM_RESET_OUT_REQUEST;
> >> diff --git a/net/sctp/stream.c b/net/sctp/stream.c
> >> index fa8371f..51a25bf 100644
> >> --- a/net/sctp/stream.c
> >> +++ b/net/sctp/stream.c
> >> @@ -162,8 +162,8 @@ int sctp_send_reset_streams(struct sctp_association *asoc,
> >>
> >>       kfree(nstr_list);
> >>
> >> -     if (!chunk) {
> >> -             retval = -ENOMEM;
> >> +     if (IS_ERR(chunk)) {
> >> +             retval = PTR_ERR(chunk);
> >>               goto out;
> >>       }
> >>
> >> @@ -482,8 +482,10 @@ struct sctp_chunk *sctp_process_strreset_inreq(
> >>       }
> >>
> >>       chunk = sctp_make_strreset_req(asoc, nums, str_p, 1, 0);
> >> -     if (!chunk)
> >> +     if (IS_ERR(chunk)) {
> >> +             chunk = NULL;
> >>               goto out;
> >> +     }
> >>
> >>       if (nums)
> >>               for (i = 0; i < nums; i++)
> >> --
> >> 2.1.0
> >>
> >>
> 

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH net] sctp: check stream reset info len before making reconf chunk
  2017-11-14 12:46       ` Neil Horman
@ 2017-11-14 12:57         ` Xin Long
  -1 siblings, 0 replies; 16+ messages in thread
From: Xin Long @ 2017-11-14 12:57 UTC (permalink / raw)
  To: Neil Horman
  Cc: network dev, linux-sctp, davem, Marcelo Ricardo Leitner,
	Dmitry Vyukov, syzkaller

On Tue, Nov 14, 2017 at 8:46 PM, Neil Horman <nhorman@tuxdriver.com> wrote:
> On Mon, Nov 13, 2017 at 11:15:40PM +0800, Xin Long wrote:
>> On Mon, Nov 13, 2017 at 11:09 PM, Neil Horman <nhorman@tuxdriver.com> wrote:
>> > On Mon, Nov 13, 2017 at 01:39:27PM +0800, Xin Long wrote:
>> >> Now when resetting stream, if both in and out flags are set, the info
>> >> len can reach:
>> >>   sizeof(struct sctp_strreset_outreq) + SCTP_MAX_STREAM(65535) +
>> >>   sizeof(struct sctp_strreset_inreq)  + SCTP_MAX_STREAM(65535)
>> >> even without duplicated stream no, this value is far greater than the
>> >> chunk's max size.
>> >>
>> >> _sctp_make_chunk doesn't do any check for this, which would cause the
>> >> skb it allocs is huge, syzbot even reported a crash due to this.
>> >>
>> >> This patch is to check stream reset info len before making reconf
>> >> chunk and return NULL if the len exceeds chunk's capacity.
>> >>
>> >> Fixes: cc16f00f6529 ("sctp: add support for generating stream reconf ssn reset request chunk")
>> >> Reported-by: Dmitry Vyukov <dvyukov@google.com>
>> >> Signed-off-by: Xin Long <lucien.xin@gmail.com>
>> >> ---
>> >>  net/sctp/sm_make_chunk.c | 7 +++++--
>> >>  net/sctp/stream.c        | 8 +++++---
>> >>  2 files changed, 10 insertions(+), 5 deletions(-)
>> >>
>> >> diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c
>> >> index 514465b..a21328a 100644
>> >> --- a/net/sctp/sm_make_chunk.c
>> >> +++ b/net/sctp/sm_make_chunk.c
>> >> @@ -3598,14 +3598,17 @@ struct sctp_chunk *sctp_make_strreset_req(
>> >>       __u16 stream_len = stream_num * 2;
>> >>       struct sctp_strreset_inreq inreq;
>> >>       struct sctp_chunk *retval;
>> >> -     __u16 outlen, inlen;
>> >> +     int outlen, inlen;
>> >>
>> >>       outlen = (sizeof(outreq) + stream_len) * out;
>> >>       inlen = (sizeof(inreq) + stream_len) * in;
>> >>
>> >> +     if (outlen + inlen > SCTP_MAX_CHUNK_LEN - sizeof(struct sctp_chunkhdr))
>> >> +             return ERR_PTR(-EINVAL);
>> >> +
>> > Why all the ERR_PTR manipulations here?  Just returning NULL, like the fuction
>> > has been doing is sufficient to set ENOMEM at both call sites
>> I don't like ERR_PTR handling here either,
>> But it shouldn't be ENOMEM, should it ?
>>
>> It may confuse users, but I'm also ok to let it just return
>> ENOMEM as you wish. wdyt ?
>>
> I'm ok with ENOMEM.  If someone tries to reconf the streams with huge values,
> ENOMEM makes sense to me
okay, thanks.

I will move the check to sctp_send_reset_streams() to fix
both this one and the one Marcelo mentioned.

> Neil
>
>> >
>> > Neil
>> >
>> >>       retval = sctp_make_reconf(asoc, outlen + inlen);
>> >>       if (!retval)
>> >> -             return NULL;
>> >> +             return ERR_PTR(-ENOMEM);
>> >>
>> >>       if (outlen) {
>> >>               outreq.param_hdr.type = SCTP_PARAM_RESET_OUT_REQUEST;
>> >> diff --git a/net/sctp/stream.c b/net/sctp/stream.c
>> >> index fa8371f..51a25bf 100644
>> >> --- a/net/sctp/stream.c
>> >> +++ b/net/sctp/stream.c
>> >> @@ -162,8 +162,8 @@ int sctp_send_reset_streams(struct sctp_association *asoc,
>> >>
>> >>       kfree(nstr_list);
>> >>
>> >> -     if (!chunk) {
>> >> -             retval = -ENOMEM;
>> >> +     if (IS_ERR(chunk)) {
>> >> +             retval = PTR_ERR(chunk);
>> >>               goto out;
>> >>       }
>> >>
>> >> @@ -482,8 +482,10 @@ struct sctp_chunk *sctp_process_strreset_inreq(
>> >>       }
>> >>
>> >>       chunk = sctp_make_strreset_req(asoc, nums, str_p, 1, 0);
>> >> -     if (!chunk)
>> >> +     if (IS_ERR(chunk)) {
>> >> +             chunk = NULL;
>> >>               goto out;
>> >> +     }
>> >>
>> >>       if (nums)
>> >>               for (i = 0; i < nums; i++)
>> >> --
>> >> 2.1.0
>> >>
>> >>
>>

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH net] sctp: check stream reset info len before making reconf chunk
@ 2017-11-14 12:57         ` Xin Long
  0 siblings, 0 replies; 16+ messages in thread
From: Xin Long @ 2017-11-14 12:57 UTC (permalink / raw)
  To: Neil Horman
  Cc: network dev, linux-sctp, davem, Marcelo Ricardo Leitner,
	Dmitry Vyukov, syzkaller

On Tue, Nov 14, 2017 at 8:46 PM, Neil Horman <nhorman@tuxdriver.com> wrote:
> On Mon, Nov 13, 2017 at 11:15:40PM +0800, Xin Long wrote:
>> On Mon, Nov 13, 2017 at 11:09 PM, Neil Horman <nhorman@tuxdriver.com> wrote:
>> > On Mon, Nov 13, 2017 at 01:39:27PM +0800, Xin Long wrote:
>> >> Now when resetting stream, if both in and out flags are set, the info
>> >> len can reach:
>> >>   sizeof(struct sctp_strreset_outreq) + SCTP_MAX_STREAM(65535) +
>> >>   sizeof(struct sctp_strreset_inreq)  + SCTP_MAX_STREAM(65535)
>> >> even without duplicated stream no, this value is far greater than the
>> >> chunk's max size.
>> >>
>> >> _sctp_make_chunk doesn't do any check for this, which would cause the
>> >> skb it allocs is huge, syzbot even reported a crash due to this.
>> >>
>> >> This patch is to check stream reset info len before making reconf
>> >> chunk and return NULL if the len exceeds chunk's capacity.
>> >>
>> >> Fixes: cc16f00f6529 ("sctp: add support for generating stream reconf ssn reset request chunk")
>> >> Reported-by: Dmitry Vyukov <dvyukov@google.com>
>> >> Signed-off-by: Xin Long <lucien.xin@gmail.com>
>> >> ---
>> >>  net/sctp/sm_make_chunk.c | 7 +++++--
>> >>  net/sctp/stream.c        | 8 +++++---
>> >>  2 files changed, 10 insertions(+), 5 deletions(-)
>> >>
>> >> diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c
>> >> index 514465b..a21328a 100644
>> >> --- a/net/sctp/sm_make_chunk.c
>> >> +++ b/net/sctp/sm_make_chunk.c
>> >> @@ -3598,14 +3598,17 @@ struct sctp_chunk *sctp_make_strreset_req(
>> >>       __u16 stream_len = stream_num * 2;
>> >>       struct sctp_strreset_inreq inreq;
>> >>       struct sctp_chunk *retval;
>> >> -     __u16 outlen, inlen;
>> >> +     int outlen, inlen;
>> >>
>> >>       outlen = (sizeof(outreq) + stream_len) * out;
>> >>       inlen = (sizeof(inreq) + stream_len) * in;
>> >>
>> >> +     if (outlen + inlen > SCTP_MAX_CHUNK_LEN - sizeof(struct sctp_chunkhdr))
>> >> +             return ERR_PTR(-EINVAL);
>> >> +
>> > Why all the ERR_PTR manipulations here?  Just returning NULL, like the fuction
>> > has been doing is sufficient to set ENOMEM at both call sites
>> I don't like ERR_PTR handling here either,
>> But it shouldn't be ENOMEM, should it ?
>>
>> It may confuse users, but I'm also ok to let it just return
>> ENOMEM as you wish. wdyt ?
>>
> I'm ok with ENOMEM.  If someone tries to reconf the streams with huge values,
> ENOMEM makes sense to me
okay, thanks.

I will move the check to sctp_send_reset_streams() to fix
both this one and the one Marcelo mentioned.

> Neil
>
>> >
>> > Neil
>> >
>> >>       retval = sctp_make_reconf(asoc, outlen + inlen);
>> >>       if (!retval)
>> >> -             return NULL;
>> >> +             return ERR_PTR(-ENOMEM);
>> >>
>> >>       if (outlen) {
>> >>               outreq.param_hdr.type = SCTP_PARAM_RESET_OUT_REQUEST;
>> >> diff --git a/net/sctp/stream.c b/net/sctp/stream.c
>> >> index fa8371f..51a25bf 100644
>> >> --- a/net/sctp/stream.c
>> >> +++ b/net/sctp/stream.c
>> >> @@ -162,8 +162,8 @@ int sctp_send_reset_streams(struct sctp_association *asoc,
>> >>
>> >>       kfree(nstr_list);
>> >>
>> >> -     if (!chunk) {
>> >> -             retval = -ENOMEM;
>> >> +     if (IS_ERR(chunk)) {
>> >> +             retval = PTR_ERR(chunk);
>> >>               goto out;
>> >>       }
>> >>
>> >> @@ -482,8 +482,10 @@ struct sctp_chunk *sctp_process_strreset_inreq(
>> >>       }
>> >>
>> >>       chunk = sctp_make_strreset_req(asoc, nums, str_p, 1, 0);
>> >> -     if (!chunk)
>> >> +     if (IS_ERR(chunk)) {
>> >> +             chunk = NULL;
>> >>               goto out;
>> >> +     }
>> >>
>> >>       if (nums)
>> >>               for (i = 0; i < nums; i++)
>> >> --
>> >> 2.1.0
>> >>
>> >>
>>

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH net] sctp: check stream reset info len before making reconf chunk
  2017-11-14  8:27         ` Xin Long
@ 2017-11-14 19:06           ` Marcelo Ricardo Leitner
  -1 siblings, 0 replies; 16+ messages in thread
From: Marcelo Ricardo Leitner @ 2017-11-14 19:06 UTC (permalink / raw)
  To: Xin Long
  Cc: Neil Horman, network dev, linux-sctp, davem, Dmitry Vyukov, syzkaller

On Tue, Nov 14, 2017 at 04:27:41PM +0800, Xin Long wrote:
> On Tue, Nov 14, 2017 at 3:54 AM, Marcelo Ricardo Leitner
> <marcelo.leitner@gmail.com> wrote:
> > On Mon, Nov 13, 2017 at 11:15:40PM +0800, Xin Long wrote:
> >> On Mon, Nov 13, 2017 at 11:09 PM, Neil Horman <nhorman@tuxdriver.com> wrote:
> >> > On Mon, Nov 13, 2017 at 01:39:27PM +0800, Xin Long wrote:
> >> >> Now when resetting stream, if both in and out flags are set, the info
> >> >> len can reach:
> >> >>   sizeof(struct sctp_strreset_outreq) + SCTP_MAX_STREAM(65535) +
> >> >>   sizeof(struct sctp_strreset_inreq)  + SCTP_MAX_STREAM(65535)
> >> >> even without duplicated stream no, this value is far greater than the
> >> >> chunk's max size.
> >> >>
> >> >> _sctp_make_chunk doesn't do any check for this, which would cause the
> >> >> skb it allocs is huge, syzbot even reported a crash due to this.
> >> >>
> >> >> This patch is to check stream reset info len before making reconf
> >> >> chunk and return NULL if the len exceeds chunk's capacity.
> >> >>
> >> >> Fixes: cc16f00f6529 ("sctp: add support for generating stream reconf ssn reset request chunk")
> >> >> Reported-by: Dmitry Vyukov <dvyukov@google.com>
> >> >> Signed-off-by: Xin Long <lucien.xin@gmail.com>
> >> >> ---
> >> >>  net/sctp/sm_make_chunk.c | 7 +++++--
> >> >>  net/sctp/stream.c        | 8 +++++---
> >> >>  2 files changed, 10 insertions(+), 5 deletions(-)
> >> >>
> >> >> diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c
> >> >> index 514465b..a21328a 100644
> >> >> --- a/net/sctp/sm_make_chunk.c
> >> >> +++ b/net/sctp/sm_make_chunk.c
> >> >> @@ -3598,14 +3598,17 @@ struct sctp_chunk *sctp_make_strreset_req(
> >> >>       __u16 stream_len = stream_num * 2;
> >
> > Unrelated, but.. won't stream_len overflow if stream_num >= 32768?
> > When called form sctp_send_reset_streams() I don't see anything
> > restricting it to such range.
> right.
> 
> >
> >> >>       struct sctp_strreset_inreq inreq;
> >> >>       struct sctp_chunk *retval;
> >> >> -     __u16 outlen, inlen;
> >> >> +     int outlen, inlen;
> >> >>
> >> >>       outlen = (sizeof(outreq) + stream_len) * out;
> >> >>       inlen = (sizeof(inreq) + stream_len) * in;
> >> >>
> >> >> +     if (outlen + inlen > SCTP_MAX_CHUNK_LEN - sizeof(struct sctp_chunkhdr))
> >> >> +             return ERR_PTR(-EINVAL);
> >> >> +
> >> > Why all the ERR_PTR manipulations here?  Just returning NULL, like the fuction
> >> > has been doing is sufficient to set ENOMEM at both call sites
> >> I don't like ERR_PTR handling here either,
> >> But it shouldn't be ENOMEM, should it ?
> >>
> >> It may confuse users, but I'm also ok to let it just return
> >> ENOMEM as you wish. wdyt ?
> >
> > Returning ENOMEM in the above error can be misleading. It's not that
> > we cannot allocate it, it's that it won't fit the packet no matter how
> > much memory we add to the system.
> right.
> 
> let's move the check into sctp_send_reset_streams()
> 
> I believe this one fixes them both:
> @@ -139,15 +139,31 @@ int sctp_send_reset_streams(struct sctp_association *asoc,
> 
>         str_nums = params->srs_number_streams;
>         str_list = params->srs_stream_list;
> -       if (out && str_nums)
> -               for (i = 0; i < str_nums; i++)
> -                       if (str_list[i] >= stream->outcnt)
> -                               goto out;
> +       if (str_nums) {
> +               int param_len = 0;
> 
> -       if (in && str_nums)
> -               for (i = 0; i < str_nums; i++)
> -                       if (str_list[i] >= stream->incnt)
> -                               goto out;
> +               if (out) {
> +                       for (i = 0; i < str_nums; i++)
> +                               if (str_list[i] >= stream->outcnt)
> +                                       goto out;
> +
> +                       param_len = str_nums * 2 +
                                 sizeof(__u16) --^

> +                                   sizeof(struct sctp_strreset_outreq);
> +               }
> +
> +               if (in) {
> +                       for (i = 0; i < str_nums; i++)
> +                               if (str_list[i] >= stream->incnt)
> +                                       goto out;
> +
> +                       param_len += str_nums * 2 +
                                  sizeof(__u16) --^

> +                                    sizeof(struct sctp_strreset_inreq);
> +               }
> +
> +               if (param_len > SCTP_MAX_CHUNK_LEN -
> +                               sizeof(struct sctp_reconf_chunk))
> +                       goto out;
> +       }
> 
> 
> and int this fix,  it's good to do all checks only when str_nums !=0.
> --
> To unsubscribe from this list: send the line "unsubscribe linux-sctp" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH net] sctp: check stream reset info len before making reconf chunk
@ 2017-11-14 19:06           ` Marcelo Ricardo Leitner
  0 siblings, 0 replies; 16+ messages in thread
From: Marcelo Ricardo Leitner @ 2017-11-14 19:06 UTC (permalink / raw)
  To: Xin Long
  Cc: Neil Horman, network dev, linux-sctp, davem, Dmitry Vyukov, syzkaller

On Tue, Nov 14, 2017 at 04:27:41PM +0800, Xin Long wrote:
> On Tue, Nov 14, 2017 at 3:54 AM, Marcelo Ricardo Leitner
> <marcelo.leitner@gmail.com> wrote:
> > On Mon, Nov 13, 2017 at 11:15:40PM +0800, Xin Long wrote:
> >> On Mon, Nov 13, 2017 at 11:09 PM, Neil Horman <nhorman@tuxdriver.com> wrote:
> >> > On Mon, Nov 13, 2017 at 01:39:27PM +0800, Xin Long wrote:
> >> >> Now when resetting stream, if both in and out flags are set, the info
> >> >> len can reach:
> >> >>   sizeof(struct sctp_strreset_outreq) + SCTP_MAX_STREAM(65535) +
> >> >>   sizeof(struct sctp_strreset_inreq)  + SCTP_MAX_STREAM(65535)
> >> >> even without duplicated stream no, this value is far greater than the
> >> >> chunk's max size.
> >> >>
> >> >> _sctp_make_chunk doesn't do any check for this, which would cause the
> >> >> skb it allocs is huge, syzbot even reported a crash due to this.
> >> >>
> >> >> This patch is to check stream reset info len before making reconf
> >> >> chunk and return NULL if the len exceeds chunk's capacity.
> >> >>
> >> >> Fixes: cc16f00f6529 ("sctp: add support for generating stream reconf ssn reset request chunk")
> >> >> Reported-by: Dmitry Vyukov <dvyukov@google.com>
> >> >> Signed-off-by: Xin Long <lucien.xin@gmail.com>
> >> >> ---
> >> >>  net/sctp/sm_make_chunk.c | 7 +++++--
> >> >>  net/sctp/stream.c        | 8 +++++---
> >> >>  2 files changed, 10 insertions(+), 5 deletions(-)
> >> >>
> >> >> diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c
> >> >> index 514465b..a21328a 100644
> >> >> --- a/net/sctp/sm_make_chunk.c
> >> >> +++ b/net/sctp/sm_make_chunk.c
> >> >> @@ -3598,14 +3598,17 @@ struct sctp_chunk *sctp_make_strreset_req(
> >> >>       __u16 stream_len = stream_num * 2;
> >
> > Unrelated, but.. won't stream_len overflow if stream_num >= 32768?
> > When called form sctp_send_reset_streams() I don't see anything
> > restricting it to such range.
> right.
> 
> >
> >> >>       struct sctp_strreset_inreq inreq;
> >> >>       struct sctp_chunk *retval;
> >> >> -     __u16 outlen, inlen;
> >> >> +     int outlen, inlen;
> >> >>
> >> >>       outlen = (sizeof(outreq) + stream_len) * out;
> >> >>       inlen = (sizeof(inreq) + stream_len) * in;
> >> >>
> >> >> +     if (outlen + inlen > SCTP_MAX_CHUNK_LEN - sizeof(struct sctp_chunkhdr))
> >> >> +             return ERR_PTR(-EINVAL);
> >> >> +
> >> > Why all the ERR_PTR manipulations here?  Just returning NULL, like the fuction
> >> > has been doing is sufficient to set ENOMEM at both call sites
> >> I don't like ERR_PTR handling here either,
> >> But it shouldn't be ENOMEM, should it ?
> >>
> >> It may confuse users, but I'm also ok to let it just return
> >> ENOMEM as you wish. wdyt ?
> >
> > Returning ENOMEM in the above error can be misleading. It's not that
> > we cannot allocate it, it's that it won't fit the packet no matter how
> > much memory we add to the system.
> right.
> 
> let's move the check into sctp_send_reset_streams()
> 
> I believe this one fixes them both:
> @@ -139,15 +139,31 @@ int sctp_send_reset_streams(struct sctp_association *asoc,
> 
>         str_nums = params->srs_number_streams;
>         str_list = params->srs_stream_list;
> -       if (out && str_nums)
> -               for (i = 0; i < str_nums; i++)
> -                       if (str_list[i] >= stream->outcnt)
> -                               goto out;
> +       if (str_nums) {
> +               int param_len = 0;
> 
> -       if (in && str_nums)
> -               for (i = 0; i < str_nums; i++)
> -                       if (str_list[i] >= stream->incnt)
> -                               goto out;
> +               if (out) {
> +                       for (i = 0; i < str_nums; i++)
> +                               if (str_list[i] >= stream->outcnt)
> +                                       goto out;
> +
> +                       param_len = str_nums * 2 +
                                 sizeof(__u16) --^

> +                                   sizeof(struct sctp_strreset_outreq);
> +               }
> +
> +               if (in) {
> +                       for (i = 0; i < str_nums; i++)
> +                               if (str_list[i] >= stream->incnt)
> +                                       goto out;
> +
> +                       param_len += str_nums * 2 +
                                  sizeof(__u16) --^

> +                                    sizeof(struct sctp_strreset_inreq);
> +               }
> +
> +               if (param_len > SCTP_MAX_CHUNK_LEN -
> +                               sizeof(struct sctp_reconf_chunk))
> +                       goto out;
> +       }
> 
> 
> and int this fix,  it's good to do all checks only when str_nums !=0.
> --
> To unsubscribe from this list: send the line "unsubscribe linux-sctp" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 

^ permalink raw reply	[flat|nested] 16+ messages in thread

end of thread, other threads:[~2017-11-14 19:06 UTC | newest]

Thread overview: 16+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-11-13  5:39 [PATCH net] sctp: check stream reset info len before making reconf chunk Xin Long
2017-11-13  5:39 ` Xin Long
2017-11-13 15:09 ` Neil Horman
2017-11-13 15:09   ` Neil Horman
2017-11-13 15:15   ` Xin Long
2017-11-13 15:15     ` Xin Long
2017-11-13 19:54     ` Marcelo Ricardo Leitner
2017-11-13 19:54       ` Marcelo Ricardo Leitner
2017-11-14  8:27       ` Xin Long
2017-11-14  8:27         ` Xin Long
2017-11-14 19:06         ` Marcelo Ricardo Leitner
2017-11-14 19:06           ` Marcelo Ricardo Leitner
2017-11-14 12:46     ` Neil Horman
2017-11-14 12:46       ` Neil Horman
2017-11-14 12:57       ` Xin Long
2017-11-14 12:57         ` Xin Long

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.