diff --git a/subsys/net/lib/lwm2m/lwm2m_registry.c b/subsys/net/lib/lwm2m/lwm2m_registry.c index 4e1f685469950..0cde5cd33ae59 100644 --- a/subsys/net/lib/lwm2m/lwm2m_registry.c +++ b/subsys/net/lib/lwm2m/lwm2m_registry.c @@ -545,6 +545,10 @@ static int lwm2m_engine_set(const struct lwm2m_obj_path *path, const void *value int ret = 0; bool changed = false; + if (value == NULL && len > 0) { + return -EINVAL; + } + if (path->level < LWM2M_PATH_LEVEL_RESOURCE) { LOG_ERR("path must have at least 3 parts"); return -EINVAL; @@ -600,7 +604,7 @@ static int lwm2m_engine_set(const struct lwm2m_obj_path *path, const void *value return ret; } - if (memcmp(data_ptr, value, len) != 0 || res_inst->data_len != len) { + if ((value != NULL && memcmp(data_ptr, value, len) != 0) || res_inst->data_len != len) { changed = true; } diff --git a/subsys/net/lib/lwm2m/lwm2m_rw_json.c b/subsys/net/lib/lwm2m/lwm2m_rw_json.c index 118cef8c472b8..c41e8ab5fcf5d 100644 --- a/subsys/net/lib/lwm2m/lwm2m_rw_json.c +++ b/subsys/net/lib/lwm2m/lwm2m_rw_json.c @@ -640,13 +640,14 @@ static int read_int(struct lwm2m_input_context *in, int64_t *value, bool accept_sign) { struct json_in_formatter_data *fd; + uint64_t temp; uint8_t *buf; int i = 0; bool neg = false; char c; /* initialize values to 0 */ - *value = 0; + temp = 0; fd = engine_get_in_user_data(in); if (!fd || (fd->object_bit_field & JSON_V_TYPE) == 0) { @@ -663,7 +664,10 @@ static int read_int(struct lwm2m_input_context *in, int64_t *value, if (c == '-' && accept_sign && i == 0) { neg = true; } else if (isdigit(c) != 0) { - *value = *value * 10 + (c - '0'); + temp = temp * 10ULL + (c - '0'); + if (temp > ((uint64_t)INT64_MAX + (neg ? 1ULL : 0ULL))) { + return -EINVAL; + } } else { /* anything else stop reading */ break; @@ -671,9 +675,7 @@ static int read_int(struct lwm2m_input_context *in, int64_t *value, i++; } - if (neg) { - *value = -*value; - } + *value = neg ? -temp : temp; return i; } diff --git a/subsys/net/lib/lwm2m/lwm2m_rw_oma_tlv.c b/subsys/net/lib/lwm2m/lwm2m_rw_oma_tlv.c index c93671612b318..4668f90751baa 100644 --- a/subsys/net/lib/lwm2m/lwm2m_rw_oma_tlv.c +++ b/subsys/net/lib/lwm2m/lwm2m_rw_oma_tlv.c @@ -425,7 +425,7 @@ static int put_s16(struct lwm2m_output_context *out, struct tlv_out_formatter_data *fd; int len; struct oma_tlv tlv; - int16_t net_value; + uint8_t net_value[sizeof(int16_t)]; if (INT8_MIN <= value && value <= INT8_MAX) { return put_s8(out, path, (int8_t)value); @@ -436,11 +436,11 @@ static int put_s16(struct lwm2m_output_context *out, return -EINVAL; } - net_value = sys_cpu_to_be16(value); + sys_put_be16(value, net_value); tlv_setup(&tlv, tlv_calc_type(fd->writer_flags), tlv_calc_id(fd->writer_flags, path), sizeof(net_value)); - len = oma_tlv_put(&tlv, out, (uint8_t *)&net_value, false); + len = oma_tlv_put(&tlv, out, net_value, false); return len; } @@ -450,7 +450,7 @@ static int put_s32(struct lwm2m_output_context *out, struct tlv_out_formatter_data *fd; int len; struct oma_tlv tlv; - int32_t net_value; + uint8_t net_value[sizeof(int32_t)]; if (INT16_MIN <= value && value <= INT16_MAX) { return put_s16(out, path, (int16_t)value); @@ -461,11 +461,11 @@ static int put_s32(struct lwm2m_output_context *out, return -EINVAL; } - net_value = sys_cpu_to_be32(value); + sys_put_be32(value, net_value); tlv_setup(&tlv, tlv_calc_type(fd->writer_flags), tlv_calc_id(fd->writer_flags, path), sizeof(net_value)); - len = oma_tlv_put(&tlv, out, (uint8_t *)&net_value, false); + len = oma_tlv_put(&tlv, out, net_value, false); return len; } @@ -476,7 +476,7 @@ static int put_s64(struct lwm2m_output_context *out, struct tlv_out_formatter_data *fd; int len; struct oma_tlv tlv; - int64_t net_value; + uint8_t net_value[sizeof(int64_t)]; if (INT32_MIN <= value && value <= INT32_MAX) { return put_s32(out, path, (int32_t)value); @@ -487,11 +487,11 @@ static int put_s64(struct lwm2m_output_context *out, return -EINVAL; } - net_value = sys_cpu_to_be64(value); + sys_put_be64(value, net_value); tlv_setup(&tlv, tlv_calc_type(fd->writer_flags), tlv_calc_id(fd->writer_flags, path), sizeof(net_value)); - len = oma_tlv_put(&tlv, out, (uint8_t *)&net_value, false); + len = oma_tlv_put(&tlv, out, net_value, false); return len; } @@ -564,8 +564,8 @@ static int put_objlnk(struct lwm2m_output_context *out, { struct tlv_out_formatter_data *fd; struct oma_tlv tlv; - int32_t net_value = sys_cpu_to_be32( - ((value->obj_id) << 16) | value->obj_inst); + uint32_t net_value = sys_cpu_to_be32( + ((uint32_t)value->obj_id << 16) | value->obj_inst); fd = engine_get_out_user_data(out); if (!fd) { @@ -583,7 +583,7 @@ static int get_number(struct lwm2m_input_context *in, int64_t *value, { struct oma_tlv tlv; int size; - int64_t temp; + uint8_t temp[sizeof(int64_t)]; int ret; size = oma_tlv_get(&tlv, in, false); @@ -596,24 +596,23 @@ static int get_number(struct lwm2m_input_context *in, int64_t *value, return -ENOMEM; } - ret = buf_read((uint8_t *)&temp, tlv.length, - CPKT_BUF_READ(in->in_cpkt), &in->offset); + ret = buf_read(temp, tlv.length, CPKT_BUF_READ(in->in_cpkt), &in->offset); if (ret < 0) { return ret; } switch (tlv.length) { case 1: - *value = (int8_t)temp; + *value = (int8_t)temp[0]; break; case 2: - *value = sys_cpu_to_be16((int16_t)temp); + *value = (int16_t)sys_get_be16(temp); break; case 4: - *value = sys_cpu_to_be32((int32_t)temp); + *value = (int32_t)sys_get_be32(temp); break; case 8: - *value = sys_cpu_to_be64(temp); + *value = (int64_t)sys_get_be64(temp); break; default: LOG_ERR("invalid length: %u", tlv.length); diff --git a/subsys/net/lib/lwm2m/lwm2m_rw_plain_text.c b/subsys/net/lib/lwm2m/lwm2m_rw_plain_text.c index 3ec69e8db8243..e95de83265116 100644 --- a/subsys/net/lib/lwm2m/lwm2m_rw_plain_text.c +++ b/subsys/net/lib/lwm2m/lwm2m_rw_plain_text.c @@ -181,7 +181,8 @@ static int plain_text_read_int(struct lwm2m_input_context *in, int64_t *value, { int i = 0; bool neg = false; - uint8_t tmp; + uint64_t temp; + uint8_t c; if (in->offset >= in->in_cpkt->offset) { /* No remaining data in the payload. */ @@ -189,18 +190,21 @@ static int plain_text_read_int(struct lwm2m_input_context *in, int64_t *value, } /* initialize values to 0 */ - *value = 0; + temp = 0; while (in->offset < in->in_cpkt->offset) { - if (buf_read_u8(&tmp, CPKT_BUF_READ(in->in_cpkt), + if (buf_read_u8(&c, CPKT_BUF_READ(in->in_cpkt), &in->offset) < 0) { break; } - if (tmp == '-' && accept_sign && i == 0) { + if (c == '-' && accept_sign && i == 0) { neg = true; - } else if (isdigit(tmp) != 0) { - *value = *value * 10 + (tmp - '0'); + } else if (isdigit(c) != 0) { + temp = temp * 10ULL + (c - '0'); + if (temp > ((uint64_t)INT64_MAX + (neg ? 1ULL : 0ULL))) { + return -EINVAL; + } } else { /* anything else stop reading */ in->offset--; @@ -210,9 +214,7 @@ static int plain_text_read_int(struct lwm2m_input_context *in, int64_t *value, i++; } - if (neg) { - *value = -*value; - } + *value = neg ? -temp : temp; return i; } diff --git a/subsys/net/lib/lwm2m/lwm2m_rw_senml_cbor.c b/subsys/net/lib/lwm2m/lwm2m_rw_senml_cbor.c index 65f6cbcc6efc9..371b1c93cea56 100644 --- a/subsys/net/lib/lwm2m/lwm2m_rw_senml_cbor.c +++ b/subsys/net/lib/lwm2m/lwm2m_rw_senml_cbor.c @@ -644,8 +644,9 @@ static int get_string(struct lwm2m_input_context *in, uint8_t *buf, size_t bufle } len = MIN(buflen-1, fd->current->record_union.union_vs.len); - - memcpy(buf, fd->current->record_union.union_vs.value, len); + if (len > 0) { + memcpy(buf, fd->current->record_union.union_vs.value, len); + } buf[len] = '\0'; fd->current = NULL; diff --git a/tests/net/lib/lwm2m/content_json/src/main.c b/tests/net/lib/lwm2m/content_json/src/main.c index 49ba101274125..1f89acf6f50ea 100644 --- a/tests/net/lib/lwm2m/content_json/src/main.c +++ b/tests/net/lib/lwm2m/content_json/src/main.c @@ -525,6 +525,10 @@ ZTEST(net_content_json, test_get_s64) TEST_PAYLOAD(TEST_RES_S64, "v", "9223372036854775807"), TEST_PAYLOAD(TEST_RES_S64, "v", "-9223372036854775808"), }; + char * const payload_overflow[] = { + TEST_PAYLOAD(TEST_RES_S64, "v", "9223372036854775808"), + TEST_PAYLOAD(TEST_RES_S64, "v", "-9223372036854775809"), + }; int64_t expected_value[] = { 0, INT64_MAX, INT64_MIN }; test_msg.path.res_id = TEST_RES_S64; @@ -536,6 +540,13 @@ ZTEST(net_content_json, test_get_s64) zassert_true(ret >= 0, "Error reported"); zassert_equal(test_s64, expected_value[i], "Invalid value parsed"); } + + for (i = 0; i < ARRAY_SIZE(payload_overflow); i++) { + test_payload_set(payload_overflow[i]); + + ret = do_write_op_json(&test_msg); + zassert_equal(ret, -EINVAL, "Error expected on too large value"); + } } ZTEST(net_content_json_nodata, test_get_s64_nodata) diff --git a/tests/net/lib/lwm2m/content_plain_text/src/main.c b/tests/net/lib/lwm2m/content_plain_text/src/main.c index 7bc77a823271f..334a210d9bf42 100644 --- a/tests/net/lib/lwm2m/content_plain_text/src/main.c +++ b/tests/net/lib/lwm2m/content_plain_text/src/main.c @@ -353,6 +353,9 @@ ZTEST(net_content_plain_text, test_get_s64) char * const payload[] = { "0", "9223372036854775807", "-9223372036854775808" }; + char * const payload_overflow[] = { + "9223372036854775808", "-9223372036854775809" + }; int64_t expected_value[] = { 0, INT64_MAX, INT64_MIN }; int64_t value; @@ -366,6 +369,13 @@ ZTEST(net_content_plain_text, test_get_s64) zassert_equal(test_in.offset, strlen(payload[i]) + 1, "Invalid packet offset"); } + + for (i = 0; i < ARRAY_SIZE(payload_overflow); i++) { + test_payload_set(payload_overflow[i]); + + ret = plain_text_reader.get_s64(&test_in, &value); + zassert_equal(ret, -EINVAL, "Error expected on too large value"); + } } ZTEST(net_content_plain_text_nodata, test_get_s64_nodata) diff --git a/tests/net/lib/lwm2m/lwm2m_rd_client/prj.conf b/tests/net/lib/lwm2m/lwm2m_rd_client/prj.conf index 775cea846a149..8eb9982979f7c 100644 --- a/tests/net/lib/lwm2m/lwm2m_rd_client/prj.conf +++ b/tests/net/lib/lwm2m/lwm2m_rd_client/prj.conf @@ -1,3 +1,4 @@ CONFIG_ZTEST=y CONFIG_ZTEST_STACK_SIZE=4096 +CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=2048 CONFIG_MP_MAX_NUM_CPUS=1 diff --git a/tests/net/lib/lwm2m/lwm2m_rd_client/src/main.c b/tests/net/lib/lwm2m/lwm2m_rd_client/src/main.c index 1d6a4e584fafc..102c6925cde6d 100644 --- a/tests/net/lib/lwm2m/lwm2m_rd_client/src/main.c +++ b/tests/net/lib/lwm2m/lwm2m_rd_client/src/main.c @@ -27,6 +27,7 @@ FAKE_VOID_FUNC(show_lwm2m_event, enum lwm2m_rd_client_event); FAKE_VOID_FUNC(show_lwm2m_observe, enum lwm2m_observe_event); static int next_event; +static struct lwm2m_ctx ctx; bool expect_lwm2m_rd_client_event(uint8_t expected_val) { @@ -198,8 +199,6 @@ ZTEST_SUITE(lwm2m_rd_client, NULL, NULL, my_suite_before, my_suite_after, NULL); ZTEST(lwm2m_rd_client, test_start_registration_ok) { - struct lwm2m_ctx ctx; - (void)memset(&ctx, 0x0, sizeof(ctx)); lwm2m_rd_client_init(); @@ -224,8 +223,6 @@ ZTEST(lwm2m_rd_client, test_start_registration_ok) ZTEST(lwm2m_rd_client, test_register_update_too_small_lifetime_to_default) { - struct lwm2m_ctx ctx; - get_u32_val = CONFIG_LWM2M_ENGINE_DEFAULT_LIFETIME / 2; lwm2m_get_u32_fake.custom_fake = lwm2m_get_u32_val; @@ -247,8 +244,6 @@ ZTEST(lwm2m_rd_client, test_register_update_too_small_lifetime_to_default) ZTEST(lwm2m_rd_client, test_timeout_resume_registration) { - struct lwm2m_ctx ctx; - (void)memset(&ctx, 0x0, sizeof(ctx)); lwm2m_rd_client_init(); @@ -270,8 +265,6 @@ ZTEST(lwm2m_rd_client, test_timeout_resume_registration) ZTEST(lwm2m_rd_client, test_start_registration_timeout) { - struct lwm2m_ctx ctx; - (void)memset(&ctx, 0x0, sizeof(ctx)); lwm2m_rd_client_init(); @@ -289,8 +282,6 @@ ZTEST(lwm2m_rd_client, test_start_registration_timeout) ZTEST(lwm2m_rd_client, test_start_registration_fail) { - struct lwm2m_ctx ctx; - (void)memset(&ctx, 0x0, sizeof(ctx)); lwm2m_rd_client_init(); @@ -315,8 +306,6 @@ ZTEST(lwm2m_rd_client, test_start_registration_fail) ZTEST(lwm2m_rd_client, test_start_registration_update) { - struct lwm2m_ctx ctx; - (void)memset(&ctx, 0x0, sizeof(ctx)); lwm2m_rd_client_init(); @@ -337,8 +326,6 @@ ZTEST(lwm2m_rd_client, test_start_registration_update) ZTEST(lwm2m_rd_client, test_rx_off) { - struct lwm2m_ctx ctx; - (void)memset(&ctx, 0x0, sizeof(ctx)); lwm2m_rd_client_init(); @@ -360,8 +347,6 @@ ZTEST(lwm2m_rd_client, test_rx_off) ZTEST(lwm2m_rd_client, test_start_registration_update_fail) { - struct lwm2m_ctx ctx; - (void)memset(&ctx, 0x0, sizeof(ctx)); lwm2m_rd_client_init(); @@ -384,8 +369,6 @@ ZTEST(lwm2m_rd_client, test_start_registration_update_fail) ZTEST(lwm2m_rd_client, test_registration_update_timeout) { - struct lwm2m_ctx ctx; - (void)memset(&ctx, 0x0, sizeof(ctx)); lwm2m_rd_client_init(); @@ -414,8 +397,6 @@ ZTEST(lwm2m_rd_client, test_registration_update_timeout) ZTEST(lwm2m_rd_client, test_deregistration_timeout) { - struct lwm2m_ctx ctx; - (void)memset(&ctx, 0x0, sizeof(ctx)); lwm2m_rd_client_init(); @@ -437,8 +418,6 @@ ZTEST(lwm2m_rd_client, test_deregistration_timeout) ZTEST(lwm2m_rd_client, test_error_on_registration_update) { - struct lwm2m_ctx ctx; - (void)memset(&ctx, 0x0, sizeof(ctx)); lwm2m_rd_client_init(); @@ -462,8 +441,6 @@ ZTEST(lwm2m_rd_client, test_error_on_registration_update) ZTEST(lwm2m_rd_client, test_network_error_on_registration) { - struct lwm2m_ctx ctx; - (void)memset(&ctx, 0x0, sizeof(ctx)); lwm2m_rd_client_init(); @@ -480,8 +457,6 @@ ZTEST(lwm2m_rd_client, test_network_error_on_registration) ZTEST(lwm2m_rd_client, test_suspend_resume_registration) { - struct lwm2m_ctx ctx; - (void)memset(&ctx, 0x0, sizeof(ctx)); lwm2m_rd_client_init(); @@ -514,8 +489,6 @@ ZTEST(lwm2m_rd_client, test_suspend_resume_registration) ZTEST(lwm2m_rd_client, test_suspend_stop_resume) { - struct lwm2m_ctx ctx; - (void)memset(&ctx, 0x0, sizeof(ctx)); lwm2m_rd_client_init(); @@ -540,8 +513,6 @@ ZTEST(lwm2m_rd_client, test_suspend_stop_resume) ZTEST(lwm2m_rd_client, test_socket_error) { - struct lwm2m_ctx ctx; - (void)memset(&ctx, 0x0, sizeof(ctx)); lwm2m_rd_client_init(); @@ -564,8 +535,6 @@ ZTEST(lwm2m_rd_client, test_socket_error) ZTEST(lwm2m_rd_client, test_socket_error_on_stop) { - struct lwm2m_ctx ctx; - (void)memset(&ctx, 0x0, sizeof(ctx)); lwm2m_rd_client_init(); @@ -590,8 +559,6 @@ ZTEST(lwm2m_rd_client, test_socket_error_on_stop) ZTEST(lwm2m_rd_client, test_no_context) { - struct lwm2m_ctx ctx; - lwm2m_rd_client_init(); zassert_equal(lwm2m_rd_client_stop(&ctx, NULL, false), -EPERM); zassert_equal(lwm2m_rd_client_pause(), -EPERM); @@ -602,8 +569,6 @@ ZTEST(lwm2m_rd_client, test_no_context) ZTEST(lwm2m_rd_client, test_engine_trigger_bootstrap) { - struct lwm2m_ctx ctx; - (void)memset(&ctx, 0x0, sizeof(ctx)); lwm2m_rd_client_init(); @@ -630,9 +595,6 @@ ZTEST(lwm2m_rd_client, test_engine_trigger_bootstrap) ZTEST(lwm2m_rd_client, test_bootstrap_timeout) { - - struct lwm2m_ctx ctx; - (void)memset(&ctx, 0x0, sizeof(ctx)); lwm2m_rd_client_init(); @@ -653,8 +615,6 @@ ZTEST(lwm2m_rd_client, test_bootstrap_timeout) ZTEST(lwm2m_rd_client, test_bootstrap_fail) { - struct lwm2m_ctx ctx; - (void)memset(&ctx, 0x0, sizeof(ctx)); lwm2m_rd_client_init(); @@ -676,9 +636,6 @@ ZTEST(lwm2m_rd_client, test_bootstrap_fail) ZTEST(lwm2m_rd_client, test_bootstrap_no_srv) { - - struct lwm2m_ctx ctx; - (void)memset(&ctx, 0x0, sizeof(ctx)); lwm2m_rd_client_init(); @@ -695,8 +652,6 @@ ZTEST(lwm2m_rd_client, test_bootstrap_no_srv) ZTEST(lwm2m_rd_client, test_disable_server) { - struct lwm2m_ctx ctx; - (void)memset(&ctx, 0x0, sizeof(ctx)); lwm2m_rd_client_init(); @@ -718,8 +673,6 @@ ZTEST(lwm2m_rd_client, test_disable_server) ZTEST(lwm2m_rd_client, test_disable_server_stop) { - struct lwm2m_ctx ctx; - (void)memset(&ctx, 0x0, sizeof(ctx)); lwm2m_rd_client_init(); @@ -744,8 +697,6 @@ ZTEST(lwm2m_rd_client, test_disable_server_stop) ZTEST(lwm2m_rd_client, test_disable_server_connect) { - struct lwm2m_ctx ctx; - (void)memset(&ctx, 0x0, sizeof(ctx)); lwm2m_rd_client_init(); @@ -774,8 +725,6 @@ ZTEST(lwm2m_rd_client, test_disable_server_connect) ZTEST(lwm2m_rd_client, test_fallback_to_bootstrap) { - struct lwm2m_ctx ctx; - (void)memset(&ctx, 0x0, sizeof(ctx)); lwm2m_rd_client_init(); @@ -796,8 +745,6 @@ ZTEST(lwm2m_rd_client, test_fallback_to_bootstrap) ZTEST(lwm2m_rd_client, test_no_srv_fallback_to_bootstrap) { - struct lwm2m_ctx ctx; - (void)memset(&ctx, 0x0, sizeof(ctx)); lwm2m_rd_client_init(); @@ -822,8 +769,6 @@ ZTEST(lwm2m_rd_client, test_no_srv_fallback_to_bootstrap) ZTEST(lwm2m_rd_client, test_start_stop_ignore_engine_fault) { - struct lwm2m_ctx ctx; - (void)memset(&ctx, 0x0, sizeof(ctx)); test_prepare_pending_message_cb(&message_reply_cb_default); @@ -857,8 +802,6 @@ ZTEST(lwm2m_rd_client, test_start_stop_ignore_engine_fault) ZTEST(lwm2m_rd_client, test_start_suspend_ignore_engine_fault) { - struct lwm2m_ctx ctx; - (void)memset(&ctx, 0x0, sizeof(ctx)); test_prepare_pending_message_cb(&message_reply_cb_default);