From 78ee0f0c2380d6a3ce1d46ae6e65eb6d24b0ad3a Mon Sep 17 00:00:00 2001 From: Seppo Takalo Date: Thu, 20 Feb 2025 13:33:25 +0200 Subject: [PATCH] net: lwm2m: Do not enforce canonical CBOR decoding Our decoder can handle decoding of non-deterministic CBOR just fine. There is no need to block valid CBOR if the server does not produce length-first deterministic CBOR. Signed-off-by: Seppo Takalo --- subsys/net/lib/lwm2m/lwm2m_rw_cbor.c | 18 ++++++++++++++++++ subsys/net/lib/lwm2m/lwm2m_senml_cbor_decode.c | 2 ++ 2 files changed, 20 insertions(+) diff --git a/subsys/net/lib/lwm2m/lwm2m_rw_cbor.c b/subsys/net/lib/lwm2m/lwm2m_rw_cbor.c index 1966f3bd930..4627d68ed21 100644 --- a/subsys/net/lib/lwm2m/lwm2m_rw_cbor.c +++ b/subsys/net/lib/lwm2m/lwm2m_rw_cbor.c @@ -237,6 +237,8 @@ static int get_s64(struct lwm2m_input_context *in, int64_t *value) { ZCBOR_STATE_D(states, 0, ICTX_BUF_R_PTR(in), ICTX_BUF_R_LEFT_SZ(in), 1, 0); + states->constant_state->enforce_canonical = false; + if (!zcbor_int64_decode(states, value)) { LOG_WRN("unable to decode a 64-bit integer value"); return -EBADMSG; @@ -253,6 +255,8 @@ static int get_s32(struct lwm2m_input_context *in, int32_t *value) { ZCBOR_STATE_D(states, 0, ICTX_BUF_R_PTR(in), ICTX_BUF_R_LEFT_SZ(in), 1, 0); + states->constant_state->enforce_canonical = false; + if (!zcbor_int32_decode(states, value)) { LOG_WRN("unable to decode a 32-bit integer value, err: %d", states->constant_state->error); @@ -270,6 +274,8 @@ static int get_float(struct lwm2m_input_context *in, double *value) { ZCBOR_STATE_D(states, 0, ICTX_BUF_R_PTR(in), ICTX_BUF_R_LEFT_SZ(in), 1, 0); + states->constant_state->enforce_canonical = false; + if (!zcbor_float_decode(states, value)) { LOG_ERR("unable to decode a floating-point value"); return -EBADMSG; @@ -289,6 +295,8 @@ static int get_string(struct lwm2m_input_context *in, uint8_t *value, size_t buf ZCBOR_STATE_D(states, 0, ICTX_BUF_R_PTR(in), ICTX_BUF_R_LEFT_SZ(in), 1, 0); + states->constant_state->enforce_canonical = false; + if (!zcbor_tstr_decode(states, &hndl)) { LOG_WRN("unable to decode a string"); return -EBADMSG; @@ -318,6 +326,8 @@ static int get_time_string(struct lwm2m_input_context *in, int64_t *value) ZCBOR_STATE_D(states, 0, ICTX_BUF_R_PTR(in), ICTX_BUF_R_LEFT_SZ(in), 1, 0); + states->constant_state->enforce_canonical = false; + if (!zcbor_tstr_decode(states, &hndl)) { return -EBADMSG; } @@ -336,6 +346,8 @@ static int get_time_numerical(struct lwm2m_input_context *in, int64_t *value) { ZCBOR_STATE_D(states, 0, ICTX_BUF_R_PTR(in), ICTX_BUF_R_LEFT_SZ(in), 1, 0); + states->constant_state->enforce_canonical = false; + if (!zcbor_int64_decode(states, value)) { LOG_WRN("unable to decode seconds since Epoch"); return -EBADMSG; @@ -355,6 +367,8 @@ static int get_time(struct lwm2m_input_context *in, time_t *value) ZCBOR_STATE_D(states, 0, ICTX_BUF_R_PTR(in), ICTX_BUF_R_LEFT_SZ(in), 1, 0); + states->constant_state->enforce_canonical = false; + success = zcbor_tag_decode(states, &tag); if (success) { @@ -405,6 +419,8 @@ static int get_bool(struct lwm2m_input_context *in, bool *value) { ZCBOR_STATE_D(states, 0, ICTX_BUF_R_PTR(in), ICTX_BUF_R_LEFT_SZ(in), 1, 0); + states->constant_state->enforce_canonical = false; + if (!zcbor_bool_decode(states, value)) { LOG_WRN("unable to decode a boolean value"); return -EBADMSG; @@ -425,6 +441,8 @@ static int get_opaque(struct lwm2m_input_context *in, uint8_t *value, size_t buf ZCBOR_STATE_D(states, 1, ICTX_BUF_R_PTR(in), ICTX_BUF_R_LEFT_SZ(in), 1, 0); + states->constant_state->enforce_canonical = false; + /* Get the CBOR header only on first read. */ if (opaque->offset == 0) { ret = zcbor_bstr_start_decode_fragment(states, &hndl); diff --git a/subsys/net/lib/lwm2m/lwm2m_senml_cbor_decode.c b/subsys/net/lib/lwm2m/lwm2m_senml_cbor_decode.c index 335c8dfbb1f..10be0e8eb0c 100644 --- a/subsys/net/lib/lwm2m/lwm2m_senml_cbor_decode.c +++ b/subsys/net/lib/lwm2m/lwm2m_senml_cbor_decode.c @@ -212,6 +212,8 @@ static bool decode_lwm2m_senml(zcbor_state_t *state, struct lwm2m_senml *result) { zcbor_log("%s\r\n", __func__); + state->constant_state->enforce_canonical = false; + bool res = (((zcbor_list_start_decode(state) && ((zcbor_multi_decode(