RIOT icon indicating copy to clipboard operation
RIOT copied to clipboard

gcoap: Avoid reading beyond defined input buffer

Open chrysn opened this issue 1 year ago • 4 comments

Contribution description

GCoAP contains a memcopy that reads beyond the bounds of the input.

This is likely not a security issue, but it does trip up ASAN (even in cases when there are otherwise no ill-effects), and it will let an error go unnoticed when trying to send too large a buffer and only copying out a portion of it.

Previously, the full retransmit buffer size was read from the source buffer and stored in the retransmit buffer. (The original length was still stored, so no other read would happen on the extraneously copied data).

I don't consider this a security issue because while there would reads to unwritten memory on retransmissions, any application that actually has its buffers and request content set up in such a way that this happens would already suffer visible breakage due to "garbage" (secrets, in the unlikely case that they are stored right behind the buffer) being retransmitted.

A second commit avoids leaking memos and the lock in two error cases (the new one and the one where I took justification for a plain return from).

Testing procedure

  • (if you like to see a result fast, run aiocoap's aiocoap-rd and substitute your local address below -- but the ASAN error happens as well without the running server)
  • run cord_lc example with
$ make all-asan
$ ./examples/cord_lc/bin/native/cord_lc.elf tap0
> cord_lc [fe80::f30:40e4:6c93:e17d]:5683 resource

Previously, this would have caused an ASAN abort; now, it merely reports whatever is in the RD (probably -4 for "nothing", or a timeout if you don't have aiocoap-rd running).

Issues/PRs references

  • TBD: Why did this not get noticed earlier? Our native tests should be run with asan builds ... or it should even be on-by-default.

chrysn avatar Apr 06 '24 09:04 chrysn

Murdock results

:heavy_check_mark: PASSED

2f7cbd3e1f96ebfe44c9d764496049f59da6e4a2 gcoap: Avoid lockup from error paths

Success Failures Total Runtime
10082 0 10083 14m:43s

Artifacts

riot-ci avatar Apr 06 '24 09:04 riot-ci

Just a reminder. I think this is only stalling because the fixup commit must be squashed.

fabian18 avatar Apr 24 '24 11:04 fabian18

Thanks for the ping, squashed. As there are unrelated errors popping up, I'm rebasing onto master.

chrysn avatar Apr 24 '24 11:04 chrysn

Although it is probably within the bounds of some static buffer where buf points to, I just saw a couple of lines below for the NON case technically we might also read beyond input bytes if no token or a token less that 8 bytes is used:

        case COAP_TYPE_NON:
            memo->send_limit = GCOAP_SEND_LIMIT_NON;
            memcpy(&memo->msg.hdr_buf[0], buf, GCOAP_HEADER_MAXLEN);
            timeout = CONFIG_GCOAP_NON_TIMEOUT_MSEC;
            break;

a MIN(len, GCOAP_HEADER_MAXLEN) would probably fix it.

fabian18 avatar Apr 24 '24 13:04 fabian18

Any reason not to press the merge button on this?

benpicco avatar Jul 24 '24 17:07 benpicco