Skip to content

Commit

Permalink
Merge pull request #21087 from maribu/backport/2024.10/sys/net/nanoco…
Browse files Browse the repository at this point in the history
…ap/buffer-overflow-separate-response

sys/net/nanocoap: fix buffer overflow in separate response handling [backport 2024.10]
  • Loading branch information
maribu authored Dec 14, 2024
2 parents b51f093 + 2da20b3 commit 90a04fc
Show file tree
Hide file tree
Showing 5 changed files with 33 additions and 8 deletions.
8 changes: 6 additions & 2 deletions examples/nanocoap_server/coap_handler.c
Original file line number Diff line number Diff line change
Expand Up @@ -209,9 +209,13 @@ static ssize_t _separate_handler(coap_pkt_t *pkt, uint8_t *buf, size_t len, coap
return coap_build_reply(pkt, COAP_CODE_SERVICE_UNAVAILABLE, buf, len, 0);
}

puts("_separate_handler(): send ACK, schedule response");
if (nanocoap_server_prepare_separate(&_separate_ctx, pkt, context)) {
puts("_separate_handler(): failed to prepare context for separate response");
/* send a reset message, as we don't support large tokens here */
return coap_build_reply(pkt, 0, buf, len, 0);
}

nanocoap_server_prepare_separate(&_separate_ctx, pkt, context);
puts("_separate_handler(): send ACK, schedule response");

event_timeout_ztimer_init(&event_timeout, ZTIMER_MSEC, EVENT_PRIO_MEDIUM,
&event_timed.super);
Expand Down
10 changes: 8 additions & 2 deletions sys/include/net/nanocoap_sock.h
Original file line number Diff line number Diff line change
Expand Up @@ -246,9 +246,15 @@ typedef struct {
* @param[out] ctx Context information for separate response
* @param[in] pkt CoAP packet to which the response will be generated
* @param[in] req Context of the CoAP request
*
* @retval 0 Success
* @retval -EOVERFLOW Storing context would have overflown buffers in @p ctx
* (e.g. RFC 8974 (module `nanocoap_token_ext`) is in
* use and token too long)
* @retval <0 Other error
*/
void nanocoap_server_prepare_separate(nanocoap_server_response_ctx_t *ctx,
coap_pkt_t *pkt, const coap_request_ctx_t *req);
int nanocoap_server_prepare_separate(nanocoap_server_response_ctx_t *ctx,
coap_pkt_t *pkt, const coap_request_ctx_t *req);

/**
* @brief Send a separate response to a CoAP request
Expand Down
21 changes: 17 additions & 4 deletions sys/net/application_layer/nanocoap/sock.c
Original file line number Diff line number Diff line change
Expand Up @@ -1052,11 +1052,22 @@ void auto_init_nanocoap_server(void)
nanocoap_server_start(&local);
}

void nanocoap_server_prepare_separate(nanocoap_server_response_ctx_t *ctx,
coap_pkt_t *pkt, const coap_request_ctx_t *req)
int nanocoap_server_prepare_separate(nanocoap_server_response_ctx_t *ctx,
coap_pkt_t *pkt, const coap_request_ctx_t *req)
{
ctx->tkl = coap_get_token_len(pkt);
memcpy(ctx->token, coap_get_token(pkt), ctx->tkl);
size_t tkl = coap_get_token_len(pkt);
if (tkl > sizeof(ctx->token)) {
DEBUG_PUTS("nanocoap: token too long for separate response ctx");
/* Legacy code may not check the return value. To still have somewhat
* sane behavior, we ask for no response for any response class.
* Getting no reply is certainly not ideal, but better than one without
* a matching token. */
memset(ctx, 0, sizeof(*ctx));
ctx->no_response = 0xff;
return -EOVERFLOW;
}
ctx->tkl = tkl;
memcpy(ctx->token, coap_get_token(pkt), tkl);
memcpy(&ctx->remote, req->remote, sizeof(ctx->remote));
#ifdef MODULE_SOCK_AUX_LOCAL
assert(req->local);
Expand All @@ -1065,6 +1076,8 @@ void nanocoap_server_prepare_separate(nanocoap_server_response_ctx_t *ctx,
uint32_t no_response = 0;
coap_opt_get_uint(pkt, COAP_OPT_NO_RESPONSE, &no_response);
ctx->no_response = no_response;

return 0;
}

int nanocoap_server_send_separate(const nanocoap_server_response_ctx_t *ctx,
Expand Down
1 change: 1 addition & 0 deletions tests/net/nanocoap_cli/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ USEMODULE += gnrc_ipv6_default

USEMODULE += nanocoap_sock
USEMODULE += nanocoap_resources
USEMODULE += fmt # scn_buf_hex() for shell cmd client_token

# boards where basic nanocoap functionality fits, but no VFS
LOW_MEMORY_BOARDS := \
Expand Down
1 change: 1 addition & 0 deletions tests/net/nanocoap_cli/nanocli_client.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
#include <stdlib.h>
#include <string.h>

#include "fmt.h"
#include "net/coap.h"
#include "net/gnrc/netif.h"
#include "net/ipv6.h"
Expand Down

0 comments on commit 90a04fc

Please sign in to comment.