Skip to content

Commit 3f82a88

Browse files
ahasztagrlubos
authored andcommitted
suit: allow for soft failures in case of unavailable payload
The directive now returns SUIT_SUCCESS in cases of unavailable payload - then this is handled as a "fail condition" by check_image_match Signed-off-by: Artur Hadasz <[email protected]>
1 parent c01d938 commit 3f82a88

File tree

10 files changed

+71
-12
lines changed

10 files changed

+71
-12
lines changed

subsys/suit/platform/app/src/suit_plat_fetch_app_specific.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,8 @@ int suit_plat_fetch_domain_specific(suit_component_t dst_handle,
5050
struct stream_sink *dst_sink, struct zcbor_string *uri)
5151
{
5252
int ret = SUIT_SUCCESS;
53+
bool hard_failure = false;
54+
5355
/* Select streamer */
5456
switch (dst_component_type) {
5557
#ifdef CONFIG_SUIT_STREAM_FETCH_SOURCE_MGR
@@ -68,13 +70,23 @@ int suit_plat_fetch_domain_specific(suit_component_t dst_handle,
6870
#endif
6971
default:
7072
ret = SUIT_ERR_UNSUPPORTED_COMPONENT_ID;
73+
hard_failure = true;
7174
break;
7275
}
7376

7477
if (ret == SUIT_SUCCESS && dst_component_type == SUIT_COMPONENT_TYPE_CACHE_POOL) {
7578
suit_dfu_cache_sink_commit(dst_sink->ctx);
7679
}
7780

81+
if (!hard_failure) {
82+
/* Failures without hard_failure flag set are treated as "unavailable payload"
83+
* failures. These are cases where suit-condition-image-match will detect
84+
* the failure, however suit-plat-fetch should return success to allow
85+
* soft failures.
86+
*/
87+
ret = SUIT_SUCCESS;
88+
}
89+
7890
return ret;
7991
}
8092

subsys/suit/platform/sdfw/src/suit_plat_fetch_sdfw_specific.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,9 +78,21 @@ int suit_plat_fetch_domain_specific(suit_component_t dst_handle,
7878
ret = suit_ipc_streamer_stream(uri->value, uri->len, dst_sink,
7979
CONFIG_SUIT_STREAM_IPC_STREAMER_CHUNK_TIMEOUT,
8080
CONFIG_SUIT_STREAM_IPC_STREAMER_REQUESTING_PERIOD);
81+
if (ret != SUIT_PLAT_SUCCESS) {
82+
ret = SUIT_PLAT_ERR_NOT_FOUND;
83+
}
8184
}
8285
#endif /* CONFIG_SUIT_STREAM_IPC_REQUESTOR */
8386

87+
if (ret == SUIT_PLAT_ERR_NOT_FOUND) {
88+
/* If we arrived here we can treat the source data as unavailable.
89+
* This is a case where suit-condition-image-match will detect
90+
* the failure, however suit-plat-fetch should return success to allow
91+
* soft failures.
92+
*/
93+
return SUIT_SUCCESS;
94+
}
95+
8496
if (ret == SUIT_PLAT_SUCCESS) {
8597
/* Flush any remaining data before reading used storage size */
8698
if (dst_sink->flush != NULL) {

subsys/suit/platform/sdfw/src/suit_plat_retrieve_manifest_sdfw_specific.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ int suit_plat_retrieve_manifest_domain_specific(struct zcbor_string *component_i
3737
ret = suit_storage_installed_envelope_get(class_id, envelope_str, envelope_len);
3838
if ((ret != SUIT_PLAT_SUCCESS) || (*envelope_str == NULL) || (*envelope_len == 0)) {
3939
LOG_ERR("Unable to find installed envelope (err: %d)", ret);
40-
ret = SUIT_ERR_UNSUPPORTED_COMPONENT_ID;
40+
ret = SUIT_ERR_UNAVAILABLE_PAYLOAD;
4141
break;
4242
}
4343

subsys/suit/platform/src/suit_plat_check_image_match.c

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,14 +64,20 @@ int suit_plat_check_image_match_mem_mapped(suit_component_t component, enum suit
6464
}
6565

6666
err = suit_generic_address_streamer_stream(data, size, &digest_sink);
67-
if (err != SUIT_PLAT_SUCCESS) {
67+
if (err == SUIT_PLAT_ERR_INVAL) {
68+
LOG_ERR("Invalid value passed to digest sink");
69+
/* This can result from an NULL/zero size source payload.
70+
* This case should be treated as a digest mismatch.
71+
*/
72+
err = SUIT_FAIL_CONDITION;
73+
} else if (err != SUIT_PLAT_SUCCESS) {
6874
LOG_ERR("Failed to stream to digest sink: %d", err);
6975
err = suit_plat_err_to_processor_err_convert(err);
7076
} else {
7177
err = suit_digest_sink_digest_match(digest_sink.ctx);
7278
if (err != SUIT_PLAT_SUCCESS) {
7379
LOG_ERR("Failed to check digest: %d", err);
74-
/* Translate error code to allow entering another branches in try-each
80+
/* Translate error code to allow entering other branches in try-each
7581
* sequence
7682
*/
7783
err = SUIT_FAIL_CONDITION;
@@ -104,6 +110,9 @@ int suit_plat_check_image_match_mfst(suit_component_t component, enum suit_cose_
104110
enum suit_cose_alg alg;
105111

106112
ret = suit_plat_retrieve_manifest(component, &envelope_str, &envelope_len);
113+
if (ret == SUIT_ERR_UNAVAILABLE_PAYLOAD) {
114+
return SUIT_FAIL_CONDITION;
115+
}
107116
if (ret != SUIT_SUCCESS) {
108117
LOG_ERR("Failed to check image digest: unable to retrieve manifest contents "
109118
"(handle: %p)\r\n",

subsys/suit/platform/src/suit_plat_retrieve_manifest.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,10 @@ int suit_plat_retrieve_manifest(suit_component_t component_handle, const uint8_t
5050
}
5151

5252
ret = suit_memptr_storage_ptr_get(handle, envelope_str, envelope_len);
53+
if ((*envelope_str == NULL) && (*envelope_len == 0)) {
54+
LOG_WRN("Pointer to manifest candidate is empty");
55+
return SUIT_ERR_UNAVAILABLE_PAYLOAD;
56+
}
5357
if ((ret != SUIT_PLAT_SUCCESS) || (*envelope_str == NULL) || (*envelope_len == 0)) {
5458
LOG_ERR("Unable to fetch pointer to manifest candidate"
5559
"(memptr storage err: %d)",

subsys/suit/stream/stream_sinks/src/suit_memptr_sink.c

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,12 @@ LOG_MODULE_REGISTER(suit_memptr_sink, CONFIG_SUIT_LOG_LEVEL);
1111

1212
static suit_plat_err_t write(void *ctx, const uint8_t *buf, size_t size);
1313
static suit_plat_err_t used_storage(void *ctx, size_t *size);
14+
static suit_plat_err_t erase(void *ctx);
1415

1516
suit_plat_err_t suit_memptr_sink_get(struct stream_sink *sink, memptr_storage_handle_t handle)
1617
{
1718
if ((sink != NULL) && (handle != NULL)) {
18-
sink->erase = NULL;
19+
sink->erase = erase;
1920
sink->write = write;
2021
sink->seek = NULL;
2122
sink->flush = NULL;
@@ -74,3 +75,23 @@ static suit_plat_err_t used_storage(void *ctx, size_t *size)
7475
LOG_ERR("Invalid argument.");
7576
return SUIT_PLAT_ERR_INVAL;
7677
}
78+
79+
static suit_plat_err_t erase(void *ctx)
80+
{
81+
suit_memptr_storage_err_t err;
82+
83+
if (ctx != NULL) {
84+
err = suit_memptr_storage_ptr_store(ctx, NULL, 0);
85+
if (err != SUIT_PLAT_SUCCESS) {
86+
/* In the current conditions suit_memptr_storage_ptr_store will only
87+
* fail with SUIT_MEMPTR_STORAGE_ERR_UNALLOCATED_RECORD
88+
*/
89+
return SUIT_PLAT_ERR_NOT_FOUND;
90+
}
91+
92+
return SUIT_PLAT_SUCCESS;
93+
}
94+
95+
LOG_ERR("Invalid argument.");
96+
return SUIT_PLAT_ERR_INVAL;
97+
}

tests/subsys/suit/check_image_match/src/main.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -397,7 +397,7 @@ ZTEST(check_image_match_tests, test_unhandled_component)
397397
err = suit_plat_check_image_match(component, suit_cose_sha256, &valid_digest);
398398

399399
/* THEN appropriate error code is returned */
400-
zassert_equal(SUIT_ERR_UNSUPPORTED_COMPONENT_ID, err, "unexpected error code: %d", err);
400+
zassert_equal(SUIT_FAIL_CONDITION, err, "unexpected error code: %d", err);
401401

402402
/* Cleanup */
403403
err = suit_plat_release_component_handle(component);

tests/subsys/suit/fetch/src/main.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -212,8 +212,9 @@ ZTEST(fetch_tests, test_fetch_to_memptr_NOK_uri_not_in_cache)
212212
setup_cache_with_sample_entries();
213213

214214
ret = suit_plat_fetch(component_handle, &uri, NULL);
215-
zassert_not_equal(ret, SUIT_SUCCESS,
216-
"suit_plat_fetch should fail - supplied uri is not in cache", ret);
215+
zassert_equal(ret, SUIT_SUCCESS,
216+
"suit_plat_fetch should succeed - supplied uri is not in cache, "
217+
"treated as empty payload");
217218

218219
ret = suit_plat_release_component_handle(component_handle);
219220
zassert_equal(ret, SUIT_SUCCESS, "Handle release failed - error %i", ret);

tests/subsys/suit/unit/app_specific/suit_plat_fetch_app/src/main.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ ZTEST(suit_platform_app_fetch_tests, test_fetch_dfu_cache_streamer_fail)
109109
zassert_equal(suit_plat_fetch_domain_specific(TEST_COMPONENT_HANDLE,
110110
SUIT_COMPONENT_TYPE_CAND_IMG, &dummy_sink,
111111
&dummy_uri),
112-
SUIT_ERR_CRASH, "Failed to return correct error code");
112+
SUIT_SUCCESS, "Failed when URI not found in cache (should succeed)");
113113
zassert_equal(suit_dfu_cache_streamer_stream_fake.call_count, 1,
114114
"Incorrect number of suit_dfu_cache_streamer_stream() calls");
115115
zassert_equal(suit_dfu_cache_streamer_stream_fake.arg0_val, dummy_uri.value,
@@ -168,7 +168,7 @@ ZTEST(suit_platform_app_fetch_tests, test_fetch_fetch_source_streamer_fail)
168168
zassert_equal(suit_plat_fetch_domain_specific(TEST_COMPONENT_HANDLE,
169169
SUIT_COMPONENT_TYPE_CACHE_POOL, &dummy_sink,
170170
&dummy_uri),
171-
SUIT_ERR_CRASH, "Failed to return correct error code");
171+
SUIT_SUCCESS, "Failed when unable to fetch payload (should succeed)");
172172
zassert_equal(suit_fetch_source_stream_fake.call_count, 1,
173173
"Incorrect number of suit_fetch_source_stream() calls");
174174
zassert_equal(suit_fetch_source_stream_fake.arg0_val, dummy_uri.value,

tests/subsys/suit/unit/suit_plat_retrieve_manifest/src/main.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -562,7 +562,7 @@ ZTEST(suit_platform_retrieve_manifest_tests, test_instld_manifest_not_found)
562562
int ret = suit_plat_retrieve_manifest(TEST_COMPONENT_HANDLE, &envelope_str, &envelope_len);
563563

564564
/* THEN manifest is not returned... */
565-
zassert_equal(SUIT_ERR_UNSUPPORTED_COMPONENT_ID, ret, "Invalid manifest retrieved");
565+
zassert_equal(SUIT_ERR_UNAVAILABLE_PAYLOAD, ret, "Invalid manifest retrieved");
566566

567567
/* ... and component ID for given component handle was fetched */
568568
zassert_equal(suit_plat_component_id_get_fake.call_count, 1,
@@ -606,7 +606,7 @@ ZTEST(suit_platform_retrieve_manifest_tests, test_instld_manifest_invalid_addres
606606
int ret = suit_plat_retrieve_manifest(TEST_COMPONENT_HANDLE, &envelope_str, &envelope_len);
607607

608608
/* THEN manifest is not returned... */
609-
zassert_equal(SUIT_ERR_UNSUPPORTED_COMPONENT_ID, ret, "Invalid manifest retrieved");
609+
zassert_equal(SUIT_ERR_UNAVAILABLE_PAYLOAD, ret, "Invalid manifest retrieved");
610610

611611
/* ... and component ID for given component handle was fetched */
612612
zassert_equal(suit_plat_component_id_get_fake.call_count, 1,
@@ -650,7 +650,7 @@ ZTEST(suit_platform_retrieve_manifest_tests, test_instld_manifest_invalid_size)
650650
int ret = suit_plat_retrieve_manifest(TEST_COMPONENT_HANDLE, &envelope_str, &envelope_len);
651651

652652
/* THEN manifest is not returned... */
653-
zassert_equal(SUIT_ERR_UNSUPPORTED_COMPONENT_ID, ret, "Invalid manifest retrieved");
653+
zassert_equal(SUIT_ERR_UNAVAILABLE_PAYLOAD, ret, "Invalid manifest retrieved");
654654

655655
/* ... and component ID for given component handle was fetched */
656656
zassert_equal(suit_plat_component_id_get_fake.call_count, 1,

0 commit comments

Comments
 (0)