Skip to content
6 changes: 5 additions & 1 deletion subsys/net/lib/lwm2m/lwm2m_registry.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
}

Expand Down
12 changes: 7 additions & 5 deletions subsys/net/lib/lwm2m/lwm2m_rw_json.c
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand All @@ -663,17 +664,18 @@ 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;
}
i++;
}

if (neg) {
*value = -*value;
}
*value = neg ? -temp : temp;

return i;
}
Expand Down
35 changes: 17 additions & 18 deletions subsys/net/lib/lwm2m/lwm2m_rw_oma_tlv.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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;
}

Expand All @@ -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);
Expand All @@ -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;
}
Expand All @@ -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);
Expand All @@ -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;
}

Expand Down Expand Up @@ -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) {
Expand All @@ -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);
Expand All @@ -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);
Expand Down
20 changes: 11 additions & 9 deletions subsys/net/lib/lwm2m/lwm2m_rw_plain_text.c
Original file line number Diff line number Diff line change
Expand Up @@ -181,26 +181,30 @@ 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. */
return -ENODATA;
}

/* 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--;
Expand All @@ -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;
}
Expand Down
5 changes: 3 additions & 2 deletions subsys/net/lib/lwm2m/lwm2m_rw_senml_cbor.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
11 changes: 11 additions & 0 deletions tests/net/lib/lwm2m/content_json/src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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)
Expand Down
10 changes: 10 additions & 0 deletions tests/net/lib/lwm2m/content_plain_text/src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -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)
Expand Down
1 change: 1 addition & 0 deletions tests/net/lib/lwm2m/lwm2m_rd_client/prj.conf
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
CONFIG_ZTEST=y
CONFIG_ZTEST_STACK_SIZE=4096
CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=2048
CONFIG_MP_MAX_NUM_CPUS=1
Loading