Subject: Re: [sidr] rpki-rtr protocol maximum message length

From: Randy Bush <[email-masked]>
Date: Sun, 01 May 2011 11:19:37 +0200

> And while we are here ..  is this a copy and paste error that section 
> 5.6 in IPv6 prefix PDU definition allows only 0..32 min prefix length 
> for IPv6 prefix ? Can't I specify 64 as min length prefix for example ?

that was caught a while ago and is in the currently published draft.

randy

---

From: Robert Raszuk <[email-masked]>
Date: Sun, 01 May 2011 12:08:26 +0200

Hi Randy,

 > that was caught a while ago and is in the currently published draft.

Looking at ver -12 (published 4 days ago) it seems still not fixed 
there. Ref: http://tools.ietf.org/html/draft-ietf-sidr-rpki-rtr-12

---

> the longest non-error pdu is pdu 6, the ipv6 pdu.  this limits the max
> size error pdu to a fairly small size.

PDU sizes are irrelevant as error-report allows "Arbitrary Text" which 
is not size limited in the current draft.

I am not sure about you but for me malloc(sizeof("fairly small size")) 
does not compile well ;-).

R.

---

From: Randy Bush <[email-masked]>
Date: Sun, 01 May 2011 13:00:00 +0200

> there. Ref: http://tools.ietf.org/html/draft-ietf-sidr-rpki-rtr-12

sorry, that one was not caught until -13, which i'll drop out when any
other significant changes are in.

> is not size limited in the current draft.

shall i put in "don't be stupid?"

> does not compile well ;-).

i did not realize you wrote code.

randy

---

From: Paul Hoffman <[email-masked]>
Date: Tue, 31 May 2011 09:40:01 -0700

On Apr 30, 2011, at 11:14 PM, Randy Bush wrote:

>> Most of the messages in the protocol are nice and small messages, but
>> the error-report message can be of arbitrary size since it can have
>> trailing diagnostic text...
>> 
>> Can we specify a maximum value for length of this message?  A cache
>> implementation can send a huge amount of diagnostic text in an
>> error-report message and have it still be  a valid message for the
>> router to parse...  It should be capped at a few K.
> 

Even with a restriction on the size of the arbitrary text, that statement is not completely true. An Error PDU can be sent for another Error PDU, ad infinitum; these could apply to error types 0 and 1. Maybe add to section 5.9 "An Error Report PDU MUST NOT be sent for an Error Report PDU.".

To answer the initial request, it seems reasonable to specify "the length of the Arbitrary Text of Error Diagnostic Message MUST NOT be longer than 200 octets". That keeps the length of the entire PDU under the semi-magic 256 octets for the current version of the protocol and yet gives bloviators such as myself plenty of room in our error messages.

--Paul Hoffman

---

From: Randy Bush <[email-masked]>
Date: Tue, 31 May 2011 20:23:46 +0300

> 1. Maybe add to section 5.9 "An Error Report PDU MUST NOT be sent for
> an Error Report PDU.".

makes sense

> To answer the initial request, it seems reasonable to specify "the
> length of the Arbitrary Text of Error Diagnostic Message MUST NOT be
> longer than 200 octets". That keeps the length of the entire PDU under
> the semi-magic 256 octets for the current version of the protocol

in what way is 256 octets semi-magic?

randy

---

From: Paul Hoffman <[email-masked]>
Date: Tue, 31 May 2011 10:52:07 -0700

> in what way is 256 octets semi-magic?

C or assembly-based implementations will need to malloc (etc.) the buffer for the incoming message. Having that fit into 256 octets could easily have some value to some implementations. There is no security problem if the cache ignores such a MUST and makes the message longer because the length is given the PDU. (Having said that, I hope router implementers of this protocol are being robust in checking the lengths in this PDU; I can already see ways to craft malicious versions of this PDU that might trigger a buffer overflow...)

One can say a lot in 200 octets, even of UTF8. 

--Paul Hoffman

---

From: Joe Touch <[email-masked]>
Date: Tue, 31 May 2011 10:56:52 -0700

On 5/31/2011 10:52 AM, Paul Hoffman wrote:
> C or assembly-based implementations will need to malloc (etc.) the
> buffer for the incoming message. Having that fit into 256 octets could
> easily have some value to some implementations. There is no security
> problem if the cache ignores such a MUST and makes the message longer
> because the length is given the PDU. (Having said that, I hope router
> implementers of this protocol are being robust in checking the lengths
> in this PDU; I can already see ways to craft malicious versions of this
> PDU that might trigger a buffer overflow...)

These are good reasons for robust implementations to check for the
message length and read only as much as the currently allocated buffer 
allows, reading more in as needed.

There's no need for a MUST for that. Attackers tend to ignore MUSTs anyway.

Joe

---

From: john heasley <[email-masked]>
Date: Tue, 31 May 2011 18:29:09 +0000

Tue, May 31, 2011 at 10:52:07AM -0700, Paul Hoffman:
> C or assembly-based implementations will need to malloc (etc.) the buffer for the incoming message. Having that fit into 256 octets could easily have some value to some implementations.

that magic could just as easily be 64 or 512 octets (or ...).  i dont
understand this concern or need of compensation that keeps coming up for
what seems like lousy implementations (of memory allocators, of ...).

---

From: Hannes Gredler <[email-masked]>
Date: Tue, 31 May 2011 20:19:10 +0200

On Tue, May 31, 2011 at 10:56:52AM -0700, Joe Touch wrote:
| 
| 
| On 5/31/2011 10:52 AM, Paul Hoffman wrote:
| >On May 31, 2011, at 10:23 AM, Randy Bush wrote:
| >
| >>>1. Maybe add to section 5.9 "An Error Report PDU MUST NOT be sent for
| >>>an Error Report PDU.".
| >>
| >>makes sense
| >>
| >>>To answer the initial request, it seems reasonable to specify "the
| >>>length of the Arbitrary Text of Error Diagnostic Message MUST NOT be
| >>>longer than 200 octets". That keeps the length of the entire PDU under
| >>>the semi-magic 256 octets for the current version of the protocol
| >>
| >>in what way is 256 octets semi-magic?
| >
| >C or assembly-based implementations will need to malloc (etc.) the
| >buffer for the incoming message. Having that fit into 256 octets could
| >easily have some value to some implementations. There is no security
| >problem if the cache ignores such a MUST and makes the message longer
| >because the length is given the PDU. (Having said that, I hope router
| >implementers of this protocol are being robust in checking the lengths
| >in this PDU; I can already see ways to craft malicious versions of this
| >PDU that might trigger a buffer overflow...)
| 
| These are good reasons for robust implementations to check for the
| message length and read only as much as the currently allocated
| buffer allows, reading more in as needed.

wonder what the normative procedure is for "too-large" messages ?

my pre-standard implementation has an inbound buffer of 4K
and resets the session if it encounters a PDU length of > 4K.

---

From: Joe Touch <[email-masked]>
Date: Tue, 31 May 2011 11:26:05 -0700

On 5/31/2011 11:19 AM, Hannes Gredler wrote:
> |>On May 31, 2011, at 10:23 AM, Randy Bush wrote:
> |>
> |>>>1. Maybe add to section 5.9 "An Error Report PDU MUST NOT be sent for
> |>>>an Error Report PDU.".
> |>>
> |>>makes sense
> |>>
> |>>>To answer the initial request, it seems reasonable to specify "the
> |>>>length of the Arbitrary Text of Error Diagnostic Message MUST NOT be
> |>>>longer than 200 octets". That keeps the length of the entire PDU under
> |>>>the semi-magic 256 octets for the current version of the protocol
> |>>
> |>>in what way is 256 octets semi-magic?
> |>
> |>C or assembly-based implementations will need to malloc (etc.) the
> |>buffer for the incoming message. Having that fit into 256 octets could
> |>easily have some value to some implementations. There is no security
> |>problem if the cache ignores such a MUST and makes the message longer
> |>because the length is given the PDU. (Having said that, I hope router
> |>implementers of this protocol are being robust in checking the lengths
> |>in this PDU; I can already see ways to craft malicious versions of this
> |>PDU that might trigger a buffer overflow...)
> |
> and resets the session if it encounters a PDU length of>  4K.

That makes an easy DOS attack.

It's better to:

- allocate a 4K (or whatever value you want) buffer
- read up to the first 4K
- check to see if there's more to read, and allocate more buffer space 
or read it into the first buffer (after the first 4K has been parsed)

Either way, there's no reason for a *protocol action* to deal with a 
receiver buffering issue.

Joe

---

From: Randy Bush <[email-masked]>
Date: Tue, 31 May 2011 21:28:36 +0300

> wonder what the normative procedure is for "too-large" messages ?

anything over 246.34 octets should have every other nibble removed,
then repacked, and the procedure repeated until it is under 246.34
octets.

i'll get that into the next draft.

can we please keep the idr out of sidr?

randy

---

From: Hannes Gredler <[email-masked]>
Date: Wed, 1 Jun 2011 08:57:54 +0200

On Tue, May 31, 2011 at 11:26:05AM -0700, Joe Touch wrote:
| 
| 
| On 5/31/2011 11:19 AM, Hannes Gredler wrote:
| >On Tue, May 31, 2011 at 10:56:52AM -0700, Joe Touch wrote:
| >|
| >|
| >| On 5/31/2011 10:52 AM, Paul Hoffman wrote:
| >|>On May 31, 2011, at 10:23 AM, Randy Bush wrote:
| >|>
| >|>>>1. Maybe add to section 5.9 "An Error Report PDU MUST NOT be sent for
| >|>>>an Error Report PDU.".
| >|>>
| >|>>makes sense
| >|>>
| >|>>>To answer the initial request, it seems reasonable to specify "the
| >|>>>length of the Arbitrary Text of Error Diagnostic Message MUST NOT be
| >|>>>longer than 200 octets". That keeps the length of the entire PDU under
| >|>>>the semi-magic 256 octets for the current version of the protocol
| >|>>
| >|>>in what way is 256 octets semi-magic?
| >|>
| >|>C or assembly-based implementations will need to malloc (etc.) the
| >|>buffer for the incoming message. Having that fit into 256 octets could
| >|>easily have some value to some implementations. There is no security
| >|>problem if the cache ignores such a MUST and makes the message longer
| >|>because the length is given the PDU. (Having said that, I hope router
| >|>implementers of this protocol are being robust in checking the lengths
| >|>in this PDU; I can already see ways to craft malicious versions of this
| >|>PDU that might trigger a buffer overflow...)
| >|
| >| These are good reasons for robust implementations to check for the
| >| message length and read only as much as the currently allocated
| >| buffer allows, reading more in as needed.
| >
| >wonder what the normative procedure is for "too-large" messages ?
| >
| >my pre-standard implementation has an inbound buffer of 4K
| >and resets the session if it encounters a PDU length of>  4K.
| 
| That makes an easy DOS attack.

i fail to see why max-PDU size spelled out in a protocol-spec is
a pre-cursor to a DOS attack. as long as the message integrity of
your TCP session is preserved (e.g. MD5, AO) its perfectly letigimate
to flap a session if i do not like what i see.
 
| It's better to:
| 
| - allocate a 4K (or whatever value you want) buffer
| - read up to the first 4K
| - check to see if there's more to read, and allocate more buffer
| space or read it into the first buffer (after the first 4K has been
| parsed)

i am not so sure about wether the above is really "better", since
there is a price to pay. in the above you are assuming that each
input parser is a true "stream parser" such that the entire parsing
context is saved when e.g. a PDU is scattered across two buffers.

e.g. consider an IPV4 Prefix where the first part is in buffer #1 and the
reminder is in buffer #2.

--- Buffer 1

   [ ... ]

   .-------------------------------------------.
   | Protocol |   PDU    |                     |
   | Version  |   Type   |    reserved = zero  |
   |    0     |    4     |                     |
   +-------------------------------------------+
   |                                           |
   |                 Length=20                 |
   |                                           |
   +-------------------------------------------+
   |          |  Prefix  |   Max    |          |
   |  Flags   |  Length  |  Length  |   zero   |
   |          |   0..32  |   0..32  |          |
   +-------------------------------------------+
   |                                           |
   |                IPv4 Prefix                |
   |                                           |
   +-------------------------------------------+

--- End of Buffer 1

Buffer 2

   +-------------------------------------------+
   |                                           |
   |         Autonomous System Number          |
   |                                           |
   `-------------------------------------------'

   [ ... ]

lets further assume that between reading buffer 1 and buffer 2 there is
a time lag (e.g. the socket just got flow blocked). now you need to save your
previous parsing results up until the socket becomes readable again.

with max-PDU sized recv buffers the whole story gets a whole lot simpler,
as you can avoid the context saving for each and every input parser:

you just need to ask.

1. do i have enough data in the buffer for reading the PDU header ?
2. if so does the message exceed the recv buffer ?
3. do i have enough data in the buffer for parsing an entire PDU ?

| Either way, there's no reason for a *protocol action* to deal with a
| receiver buffering issue.

i find less code-complexity in input parsers a quite compelling argument.