Skip to content

Commit 779d852

Browse files
rlubosfabiobaltieri
authored andcommitted
net: lwm2m: oma_tlv: Fix UBSAN warnings about signed integers
* Simplify the logic of the get_number() function to address the corner cases reported by UBSAN regarding byte-swapping signed integer values. The existing logic was actually only valid for little-endian systems, as it expected that the bytes written from the packet buffer will be stored at the beginning of the int64_t memory, plus the actual byte-swapping with signed integer casts inside was hard to follow. Switch to a plain uint8_t buffer for integer readout, and use dedicated system function to convert the big-endian data in the buffer into unsigned integer in the system endianness, followed by the final cast to a signed value. * Add explicit cast to uint32_t in put_objlnk() to prevent warning about not-fitting integer after byte shift, and update the result type to uint32_t as well. * Switch to buffer with sys_put_be16/32/64 when writing integers due to similar warnings about byte-swapping signed values. Signed-off-by: Robert Lubos <[email protected]>
1 parent a09fae5 commit 779d852

File tree

1 file changed

+17
-18
lines changed

1 file changed

+17
-18
lines changed

subsys/net/lib/lwm2m/lwm2m_rw_oma_tlv.c

Lines changed: 17 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -425,7 +425,7 @@ static int put_s16(struct lwm2m_output_context *out,
425425
struct tlv_out_formatter_data *fd;
426426
int len;
427427
struct oma_tlv tlv;
428-
int16_t net_value;
428+
uint8_t net_value[sizeof(int16_t)];
429429

430430
if (INT8_MIN <= value && value <= INT8_MAX) {
431431
return put_s8(out, path, (int8_t)value);
@@ -436,11 +436,11 @@ static int put_s16(struct lwm2m_output_context *out,
436436
return -EINVAL;
437437
}
438438

439-
net_value = sys_cpu_to_be16(value);
439+
sys_put_be16(value, net_value);
440440
tlv_setup(&tlv, tlv_calc_type(fd->writer_flags),
441441
tlv_calc_id(fd->writer_flags, path), sizeof(net_value));
442442

443-
len = oma_tlv_put(&tlv, out, (uint8_t *)&net_value, false);
443+
len = oma_tlv_put(&tlv, out, net_value, false);
444444
return len;
445445
}
446446

@@ -450,7 +450,7 @@ static int put_s32(struct lwm2m_output_context *out,
450450
struct tlv_out_formatter_data *fd;
451451
int len;
452452
struct oma_tlv tlv;
453-
int32_t net_value;
453+
uint8_t net_value[sizeof(int32_t)];
454454

455455
if (INT16_MIN <= value && value <= INT16_MAX) {
456456
return put_s16(out, path, (int16_t)value);
@@ -461,11 +461,11 @@ static int put_s32(struct lwm2m_output_context *out,
461461
return -EINVAL;
462462
}
463463

464-
net_value = sys_cpu_to_be32(value);
464+
sys_put_be32(value, net_value);
465465
tlv_setup(&tlv, tlv_calc_type(fd->writer_flags),
466466
tlv_calc_id(fd->writer_flags, path), sizeof(net_value));
467467

468-
len = oma_tlv_put(&tlv, out, (uint8_t *)&net_value, false);
468+
len = oma_tlv_put(&tlv, out, net_value, false);
469469

470470
return len;
471471
}
@@ -476,7 +476,7 @@ static int put_s64(struct lwm2m_output_context *out,
476476
struct tlv_out_formatter_data *fd;
477477
int len;
478478
struct oma_tlv tlv;
479-
int64_t net_value;
479+
uint8_t net_value[sizeof(int64_t)];
480480

481481
if (INT32_MIN <= value && value <= INT32_MAX) {
482482
return put_s32(out, path, (int32_t)value);
@@ -487,11 +487,11 @@ static int put_s64(struct lwm2m_output_context *out,
487487
return -EINVAL;
488488
}
489489

490-
net_value = sys_cpu_to_be64(value);
490+
sys_put_be64(value, net_value);
491491
tlv_setup(&tlv, tlv_calc_type(fd->writer_flags),
492492
tlv_calc_id(fd->writer_flags, path), sizeof(net_value));
493493

494-
len = oma_tlv_put(&tlv, out, (uint8_t *)&net_value, false);
494+
len = oma_tlv_put(&tlv, out, net_value, false);
495495
return len;
496496
}
497497

@@ -564,8 +564,8 @@ static int put_objlnk(struct lwm2m_output_context *out,
564564
{
565565
struct tlv_out_formatter_data *fd;
566566
struct oma_tlv tlv;
567-
int32_t net_value = sys_cpu_to_be32(
568-
((value->obj_id) << 16) | value->obj_inst);
567+
uint32_t net_value = sys_cpu_to_be32(
568+
((uint32_t)value->obj_id << 16) | value->obj_inst);
569569

570570
fd = engine_get_out_user_data(out);
571571
if (!fd) {
@@ -583,7 +583,7 @@ static int get_number(struct lwm2m_input_context *in, int64_t *value,
583583
{
584584
struct oma_tlv tlv;
585585
int size;
586-
int64_t temp;
586+
uint8_t temp[sizeof(int64_t)];
587587
int ret;
588588

589589
size = oma_tlv_get(&tlv, in, false);
@@ -596,24 +596,23 @@ static int get_number(struct lwm2m_input_context *in, int64_t *value,
596596
return -ENOMEM;
597597
}
598598

599-
ret = buf_read((uint8_t *)&temp, tlv.length,
600-
CPKT_BUF_READ(in->in_cpkt), &in->offset);
599+
ret = buf_read(temp, tlv.length, CPKT_BUF_READ(in->in_cpkt), &in->offset);
601600
if (ret < 0) {
602601
return ret;
603602
}
604603

605604
switch (tlv.length) {
606605
case 1:
607-
*value = (int8_t)temp;
606+
*value = (int8_t)temp[0];
608607
break;
609608
case 2:
610-
*value = sys_cpu_to_be16((int16_t)temp);
609+
*value = (int16_t)sys_get_be16(temp);
611610
break;
612611
case 4:
613-
*value = sys_cpu_to_be32((int32_t)temp);
612+
*value = (int32_t)sys_get_be32(temp);
614613
break;
615614
case 8:
616-
*value = sys_cpu_to_be64(temp);
615+
*value = (int64_t)sys_get_be64(temp);
617616
break;
618617
default:
619618
LOG_ERR("invalid length: %u", tlv.length);

0 commit comments

Comments
 (0)