obgm / libcoap

A CoAP (RFC 7252) implementation in C

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Block-Wise Transfers, the SZX does not match the size of the payload in bytes.

sabor12345 opened this issue · comments

Environment

  • Build System: [Make]
  • Operating System: [Linux]
  • Operating System Version: [Debian GNU/Linux 12]
  • Hosted Environment: [None]

libcoap Configuration Summary

`$ ./configure --prefix=/home/libcoap_2023_10_22/libcoap/build --disable-manpages

#define PACKAGE_NAME "libcoap"
| #define PACKAGE_TARNAME "libcoap"
| #define PACKAGE_VERSION "4.3.1"
| #define PACKAGE_STRING "libcoap 4.3.1"

Problem Description

According to the RFC 7959:
"The block size implied by SZX MUST match the size of the payload in bytes, if the M bit is set."

The server/client accepts the block even if the SZX field is not matching the payload and M bit is set, and asks for the request.

Expected Behavior

I guess the server/client should not accept the block if the M bit is set and SZX field is not matching the size of the payload.

Actual Behavior

The server accepts the block even if the SZX field is not matching the payload and M bit is set, and asks for the request.

Steps to reproduce

You can use the server and client examples in the example folder. Do a put request to the server, using the example_data resource. Whenever the server receives the second block, you can change the SZX field to something smaller or bigger.

Debug Logs

The server receives this:
v:1 t:CON c:PUT i:3dc1 {02000000000003} [ Uri-Path:example_data, Content-Format:application/link-format, Block1:1/M/16, Size1:111, Request-Tag:0x117e8661 ] :: 'oeeeeeeedasfdsafdsafdsfdsdsadsad'

Here the M bit is set and block szx indicates 16 bytes but the payload is 32 bytes. 
The server produces this: 
v:1 t:ACK c:2.31 i:3dc1 {02000000000003} [ Block1:1/M/16 ]

@sabor12345 Thanks for raising this.

It would appear that you are deliberately modifying the transmitted second packet's block's SZX parameter before transmission, as I would be expecting the libcoap client logic to be transmitting the payload based on the SZX parameter of the first block (and adding in that SZX value) unless the server deliberately reduced the SZX value in the first 2.31 (Continue) response. The libcoap logic is broken at this point if you did not do the modify as it is not obeying the MUST in RFC7959. It would be good to see that first response.

That said, the server should be doing something with the oversized payload based on M set and SZX. The RFC does not indicate what the server response should be. There is nothing to say that it cannot ignore payload data beyond the SZX size, or perhaps return a 4.00 (Bad Request) etc. libcoap currently truncates the received data payload to the SZX defined length, ignoring the remaining bytes.

It needs to be noted that if BERT is in use (RFC8323) where SZX has the value of 7, the payload can be multiple 1024 sized chunks.

Hi!

It is possible to do the inverse as well, to send a put request where the SZX field indicates 64 bytes but the payload is 32 bytes. If libcoap proceeds with the defined SZX length, will it store 32 bytes of random data?


Server receives this:

v:1 t:CON c:PUT i:abaf {02000000000003} [ Uri-Path:example_data, Content-Format:application/link-format, Block1:1/M/64, Size1:111, Request-Tag:0xc9ece585 ] :: 'oeeeeeeedasfdsafdsafdsfdsdsadsad'

and produces this:

v:1 t:ACK c:2.31 i:abaf {02000000000003} [ Block1:1/M/64 ]

Yes, it appears that you end up with random data. I will look at getting it fixed.

Fixed in #1286.

Note that the random data is because is because only part of the buffer was updated as the data length was short, not that random bytes beyond the end of the data were copied over.

Hi!

The same thing happens when the client receives a response where the M bit is set and the SZX field indicates 32 bytes but the actual payload size is 16 bytes. I guess the client will proceed with the SZX field and store random data?

Client receives this and proceeds:

v:1 t:ACK c:2.05 i:9122 {02000000000002} [ ETag:0x01, Content-Format:application/link-format, Block2:1/M/32, Size2:151 ] :: 'al Info";ct=0,</'

@sabor12345 Fixed in #1294, which is waiting to be merged. Please confirm that this works for you.

[Note that the input buffer only has 16 bytes copied across in your case, the following 16 bytes are unchanged, so any random data is that which pre-existed in the input puffer.]

Can this be closed now?