Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

lwm2m: Check CoAP header offset #84550

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 37 additions & 1 deletion subsys/net/lib/lwm2m/lwm2m_message_handling.c
Original file line number Diff line number Diff line change
Expand Up @@ -379,6 +379,11 @@ STATIC int build_msg_block_for_send(struct lwm2m_message *msg, uint16_t block_nu
return ret;
}

ret = lwm2m_check_header_boundary(msg->cpkt.offset);
if (ret < 0) {
return ret;
}

payload_size = MIN(complete_payload_len - block_num * block_size_bytes, block_size_bytes);
ret = buf_append(CPKT_BUF_WRITE(&msg->cpkt),
complete_payload + (block_num * block_size_bytes), payload_size);
Expand Down Expand Up @@ -488,6 +493,17 @@ void lwm2m_engine_context_init(struct lwm2m_ctx *client_ctx)
}
/* utility functions */

int lwm2m_check_header_boundary(const uint16_t offset)
{
if (offset >= CONFIG_LWM2M_ENGINE_MESSAGE_HEADER_SIZE) {
LOG_ERR("CoAP header size exceeded, increase the value of %s to at least %" PRIu16
"",
"CONFIG_LWM2M_ENGINE_MESSAGE_HEADER_SIZE", offset);
return -ENOMEM;
}
return 0;
}

int coap_options_to_path(struct coap_option *opt, int options_count,
struct lwm2m_obj_path *path)
{
Expand Down Expand Up @@ -1817,6 +1833,11 @@ int lwm2m_perform_read_op(struct lwm2m_message *msg, uint16_t content_format)
return ret;
}

ret = lwm2m_check_header_boundary(msg->out.out_cpkt->offset);
if (ret < 0) {
return ret;
}

/* store original path values so we can change them during processing */
memcpy(&temp_path, &msg->path, sizeof(temp_path));

Expand Down Expand Up @@ -1917,6 +1938,11 @@ int lwm2m_discover_handler(struct lwm2m_message *msg, bool is_bootstrap)
return ret;
}

ret = lwm2m_check_header_boundary(msg->cpkt.offset);
if (ret < 0) {
return ret;
}

/*
* Add required prefix for bootstrap discovery (5.2.7.3).
* For device management discovery, `engine_put_begin()` adds nothing.
Expand Down Expand Up @@ -2912,7 +2938,12 @@ void lwm2m_udp_receive(struct lwm2m_ctx *client_ctx, uint8_t *buf, uint16_t buf_
}

client_ctx->processed_req = NULL;
lwm2m_send_message_async(msg);
r = lwm2m_send_message_async(msg);
if (r < 0) {
LOG_ERR("Failed to send response (err: %d)", r);
lwm2m_reset_message(msg, true);
return;
}
} else {
LOG_DBG("No handler for response");
}
Expand Down Expand Up @@ -3245,6 +3276,11 @@ int lwm2m_perform_composite_read_op(struct lwm2m_message *msg, uint16_t content_
return ret;
}

ret = lwm2m_check_header_boundary(msg->cpkt.offset);
if (ret < 0) {
return ret;
}

/* Add object start mark */
engine_put_begin(&msg->out, &msg->path);

Expand Down
2 changes: 2 additions & 0 deletions subsys/net/lib/lwm2m/lwm2m_message_handling.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@
#define NUM_OUTPUT_BLOCK_CONTEXT CONFIG_LWM2M_NUM_OUTPUT_BLOCK_CONTEXT
#endif

/* Check the LwM2M header does not exceed configured limits */
int lwm2m_check_header_boundary(uint16_t offset);
int coap_options_to_path(struct coap_option *opt, int options_count,
struct lwm2m_obj_path *path);
/* LwM2M message functions */
Expand Down
27 changes: 24 additions & 3 deletions subsys/net/lib/lwm2m/lwm2m_rd_client.c
Original file line number Diff line number Diff line change
Expand Up @@ -781,11 +781,20 @@ static int sm_send_bootstrap_registration(void)
query_buffer, strlen(query_buffer));
}

ret = lwm2m_check_header_boundary(msg->cpkt.offset);
if (ret < 0) {
goto cleanup;
}

/* log the bootstrap attempt */
LOG_DBG("Register ID with bootstrap server as '%s'",
query_buffer);

lwm2m_send_message_async(msg);
ret = lwm2m_send_message_async(msg);
if (ret < 0) {
LOG_ERR("Failed to send bootstrap message (err: %d)", ret);
goto cleanup;
}

return 0;

Expand Down Expand Up @@ -978,6 +987,11 @@ static int sm_send_registration(bool send_obj_support_data,
goto cleanup;
}

ret = lwm2m_check_header_boundary(msg->cpkt.offset);
if (ret < 0) {
goto cleanup;
}

msg->out.out_cpkt = &msg->cpkt;
msg->out.writer = &link_format_writer;

Expand All @@ -987,7 +1001,10 @@ static int sm_send_registration(bool send_obj_support_data,
}
}

lwm2m_send_message_async(msg);
ret = lwm2m_send_message_async(msg);
if (ret < 0) {
goto cleanup;
}

/* log the registration attempt */
LOG_DBG("registration sent [%s]",
Expand Down Expand Up @@ -1259,7 +1276,11 @@ static int sm_do_deregister(void)

LOG_INF("Deregister from '%s'", client.server_ep);

lwm2m_send_message_async(msg);
ret = lwm2m_send_message_async(msg);
if (ret < 0) {
LOG_ERR("Failed to send deregistration message (err:%d).", ret);
goto cleanup;
}

set_sm_state(ENGINE_DEREGISTER_SENT);
return 0;
Expand Down
51 changes: 30 additions & 21 deletions tests/net/lib/lwm2m/content_json/src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,7 @@ static void context_reset(void)

test_msg.cpkt.data = test_msg.msg_data;
test_msg.cpkt.max_len = sizeof(test_msg.msg_data);
test_msg.cpkt.offset = 0;
}

static void test_payload_set(const char *payload)
Expand Down Expand Up @@ -159,17 +160,18 @@ ZTEST(net_content_json, test_put_s8)
{
int ret;
int i;
uint16_t offset = 0;
int8_t value[] = { 0, INT8_MAX, INT8_MIN };
char * const expected_payload[] = {
TEST_PAYLOAD(TEST_RES_S8, "v", "0"),
TEST_PAYLOAD(TEST_RES_S8, "v", "127"),
TEST_PAYLOAD(TEST_RES_S8, "v", "-128"),
};

test_msg.path.res_id = TEST_RES_S8;

for (i = 0; i < ARRAY_SIZE(expected_payload); i++) {
context_reset();
test_msg.path.res_id = TEST_RES_S8;
uint16_t offset = 0;

test_s8 = value[i];

ret = do_read_op_json(&test_msg, COAP_CONTENT_FORMAT_APP_JSON);
Expand Down Expand Up @@ -201,17 +203,18 @@ ZTEST(net_content_json, test_put_s16)
{
int ret;
int i;
uint16_t offset = 0;
int16_t value[] = { 0, INT16_MAX, INT16_MIN };
char * const expected_payload[] = {
TEST_PAYLOAD(TEST_RES_S16, "v", "0"),
TEST_PAYLOAD(TEST_RES_S16, "v", "32767"),
TEST_PAYLOAD(TEST_RES_S16, "v", "-32768"),
};

test_msg.path.res_id = TEST_RES_S16;

for (i = 0; i < ARRAY_SIZE(expected_payload); i++) {
context_reset();
test_msg.path.res_id = TEST_RES_S16;
uint16_t offset = 0;

test_s16 = value[i];

ret = do_read_op_json(&test_msg, COAP_CONTENT_FORMAT_APP_JSON);
Expand Down Expand Up @@ -243,17 +246,18 @@ ZTEST(net_content_json, test_put_s32)
{
int ret;
int i;
uint16_t offset = 0;
int32_t value[] = { 0, INT32_MAX, INT32_MIN };
char * const expected_payload[] = {
TEST_PAYLOAD(TEST_RES_S32, "v", "0"),
TEST_PAYLOAD(TEST_RES_S32, "v", "2147483647"),
TEST_PAYLOAD(TEST_RES_S32, "v", "-2147483648"),
};

test_msg.path.res_id = TEST_RES_S32;

for (i = 0; i < ARRAY_SIZE(expected_payload); i++) {
context_reset();
test_msg.path.res_id = TEST_RES_S32;
uint16_t offset = 0;

test_s32 = value[i];

ret = do_read_op_json(&test_msg, COAP_CONTENT_FORMAT_APP_JSON);
Expand Down Expand Up @@ -285,17 +289,18 @@ ZTEST(net_content_json, test_put_s64)
{
int ret;
int i;
uint16_t offset = 0;
int64_t value[] = { 0, INT64_MAX, INT64_MIN };
char * const expected_payload[] = {
TEST_PAYLOAD(TEST_RES_S64, "v", "0"),
TEST_PAYLOAD(TEST_RES_S64, "v", "9223372036854775807"),
TEST_PAYLOAD(TEST_RES_S64, "v", "-9223372036854775808"),
};

test_msg.path.res_id = TEST_RES_S64;

for (i = 0; i < ARRAY_SIZE(expected_payload); i++) {
context_reset();
test_msg.path.res_id = TEST_RES_S64;
uint16_t offset = 0;

test_s64 = value[i];

ret = do_read_op_json(&test_msg, COAP_CONTENT_FORMAT_APP_JSON);
Expand Down Expand Up @@ -357,7 +362,6 @@ ZTEST(net_content_json, test_put_float)
{
int ret;
int i;
uint16_t offset = 0;
double value[] = { 0., 0.123, -0.987, 3., -10., 2.333, -123.125 };
char * const expected_payload[] = {
TEST_PAYLOAD(TEST_RES_FLOAT, "v", "0.0"),
Expand All @@ -369,9 +373,11 @@ ZTEST(net_content_json, test_put_float)
TEST_PAYLOAD(TEST_RES_FLOAT, "v", "-123.125"),
};

test_msg.path.res_id = TEST_RES_FLOAT;

for (i = 0; i < ARRAY_SIZE(expected_payload); i++) {
context_reset();
test_msg.path.res_id = TEST_RES_FLOAT;
uint16_t offset = 0;

test_float = value[i];

ret = do_read_op_json(&test_msg, COAP_CONTENT_FORMAT_APP_JSON);
Expand Down Expand Up @@ -403,16 +409,18 @@ ZTEST(net_content_json, test_put_bool)
{
int ret;
int i;
uint16_t offset = 0;

bool value[] = { true, false };
char * const expected_payload[] = {
TEST_PAYLOAD(TEST_RES_BOOL, "bv", "true"),
TEST_PAYLOAD(TEST_RES_BOOL, "bv", "false"),
};

test_msg.path.res_id = TEST_RES_BOOL;

for (i = 0; i < ARRAY_SIZE(expected_payload); i++) {
context_reset();
test_msg.path.res_id = TEST_RES_BOOL;
uint16_t offset = 0;

test_bool = value[i];

ret = do_read_op_json(&test_msg, COAP_CONTENT_FORMAT_APP_JSON);
Expand Down Expand Up @@ -444,7 +452,6 @@ ZTEST(net_content_json, test_put_objlnk)
{
int ret;
int i;
uint16_t offset = 0;
struct lwm2m_objlnk value[] = {
{ 0, 0 }, { 1, 1 }, { LWM2M_OBJLNK_MAX_ID, LWM2M_OBJLNK_MAX_ID }
};
Expand All @@ -454,9 +461,11 @@ ZTEST(net_content_json, test_put_objlnk)
TEST_PAYLOAD(TEST_RES_OBJLNK, "ov", "\"65535:65535\""),
};

test_msg.path.res_id = TEST_RES_OBJLNK;

for (i = 0; i < ARRAY_SIZE(expected_payload); i++) {
context_reset();
test_msg.path.res_id = TEST_RES_OBJLNK;
uint16_t offset = 0;

test_objlnk = value[i];

ret = do_read_op_json(&test_msg, COAP_CONTENT_FORMAT_APP_JSON);
Expand Down
Loading
Loading