diff --git a/src/erasurecode.c b/src/erasurecode.c index 2d6d293..13e5f02 100644 --- a/src/erasurecode.c +++ b/src/erasurecode.c @@ -1025,6 +1025,11 @@ out: int liberasurecode_verify_fragment_metadata(ec_backend_t be, fragment_metadata_t *md) { + int k = be->args.uargs.k; + int m = be->args.uargs.m; + if (md->idx < 0 || (md->idx > (k + m))) { + return 1; + } if (md->backend_id != be->common.id) { return 1; } diff --git a/test/liberasurecode_test.c b/test/liberasurecode_test.c index b5239a9..e8b3179 100644 --- a/test/liberasurecode_test.c +++ b/test/liberasurecode_test.c @@ -265,6 +265,8 @@ typedef enum { MAGIC_MISMATCH, BACKEND_ID_MISMATCH, BACKEND_VERSION_MISMATCH, + FRAGIDX_INVALID, + FRAGIDX_OUT_OF_RANGE, } fragment_mismatch_scenario_t; char * get_name_from_backend_id(ec_backend_id_t be) { @@ -1411,6 +1413,7 @@ static void verify_fragment_metadata_mismatch_impl(const ec_backend_id_t be_id, uint32_t orig_libec_ver = 0; uint32_t orig_be_ver = 0; uint8_t orig_be_id = 0; + uint32_t orig_frag_idx = 0; int *skip = create_skips_array(args,-1); char *orig_data = create_buffer(orig_data_size, 'x'); int desc = liberasurecode_instance_create(be_id, args); @@ -1428,7 +1431,7 @@ static void verify_fragment_metadata_mismatch_impl(const ec_backend_id_t be_id, encoded_parity, args, skip); for (i = 0; i < num_avail_frags; i++) { char * cur_frag = avail_frags[i]; - //corrupt fragment + // corrupt fragment switch (scenario) { case LIBEC_VERSION_MISMATCH: orig_libec_ver = ((fragment_header_t*)cur_frag)->libec_version; @@ -1445,12 +1448,20 @@ static void verify_fragment_metadata_mismatch_impl(const ec_backend_id_t be_id, orig_be_ver = ((fragment_header_t*)cur_frag)->meta.backend_version; ((fragment_header_t*)cur_frag)->meta.backend_version = orig_be_ver + 1; break; + case FRAGIDX_INVALID: + orig_frag_idx = ((fragment_header_t*)cur_frag)->meta.idx; + ((fragment_header_t*)cur_frag)->meta.idx = -1; + break; + case FRAGIDX_OUT_OF_RANGE: + orig_frag_idx = ((fragment_header_t*)cur_frag)->meta.idx; + ((fragment_header_t*)cur_frag)->meta.idx = args->k + args->m + 1; + break; default: assert(false); } rc = is_invalid_fragment(desc, avail_frags[i]); assert(rc == 1); - //heal fragment + // heal fragment switch (scenario) { case LIBEC_VERSION_MISMATCH: ((fragment_header_t*)cur_frag)->libec_version = orig_libec_ver; @@ -1464,6 +1475,10 @@ static void verify_fragment_metadata_mismatch_impl(const ec_backend_id_t be_id, case BACKEND_VERSION_MISMATCH: ((fragment_header_t*)cur_frag)->meta.backend_version = orig_be_ver; break; + case FRAGIDX_INVALID: + case FRAGIDX_OUT_OF_RANGE: + ((fragment_header_t*)cur_frag)->meta.idx = orig_frag_idx; + break; default: break; } @@ -1496,6 +1511,13 @@ static void test_verify_stripe_metadata_be_ver_mismatch( verify_fragment_metadata_mismatch_impl(be_id, args, BACKEND_VERSION_MISMATCH); } +static void test_verify_stripe_metadata_frag_idx_invalid( + const ec_backend_id_t be_id, struct ec_args *args) +{ + verify_fragment_metadata_mismatch_impl(be_id, args, FRAGIDX_INVALID); + verify_fragment_metadata_mismatch_impl(be_id, args, FRAGIDX_OUT_OF_RANGE); +} + //static void test_verify_str @@ -1622,6 +1644,10 @@ struct testcase testcases[] = { test_verify_stripe_metadata_be_ver_mismatch, EC_BACKEND_FLAT_XOR_HD, CHKSUM_CRC32, .skip = false}, + {"test_verify_stripe_metadata_frag_idx_invalid", + test_verify_stripe_metadata_frag_idx_invalid, + EC_BACKEND_FLAT_XOR_HD, CHKSUM_CRC32, + .skip = false}, {"test_simple_encode_decode_over32", test_simple_encode_decode_over32, EC_BACKEND_JERASURE_RS_VAND, CHKSUM_CRC32, @@ -1687,6 +1713,10 @@ struct testcase testcases[] = { test_verify_stripe_metadata_be_ver_mismatch, EC_BACKEND_JERASURE_RS_VAND, CHKSUM_CRC32, .skip = false}, + {"test_verify_stripe_metadata_frag_idx_invalid", + test_verify_stripe_metadata_frag_idx_invalid, + EC_BACKEND_JERASURE_RS_VAND, CHKSUM_CRC32, + .skip = false}, // Jerasure RS Cauchy backend tests {"create_and_destroy_backend", test_create_and_destroy_backend, @@ -1748,6 +1778,10 @@ struct testcase testcases[] = { test_verify_stripe_metadata_be_ver_mismatch, EC_BACKEND_JERASURE_RS_CAUCHY, CHKSUM_CRC32, .skip = false}, + {"test_verify_stripe_metadata_frag_idx_invalid", + test_verify_stripe_metadata_frag_idx_invalid, + EC_BACKEND_JERASURE_RS_CAUCHY, CHKSUM_CRC32, + .skip = false}, // ISA-L tests {"create_and_destroy_backend", test_create_and_destroy_backend, @@ -1805,6 +1839,10 @@ struct testcase testcases[] = { test_verify_stripe_metadata_be_ver_mismatch, EC_BACKEND_ISA_L_RS_VAND, CHKSUM_CRC32, .skip = false}, + {"test_verify_stripe_metadata_frag_idx_invalid", + test_verify_stripe_metadata_frag_idx_invalid, + EC_BACKEND_ISA_L_RS_VAND, CHKSUM_CRC32, + .skip = false}, // shss tests {"create_and_destroy_backend", test_create_and_destroy_backend, @@ -1862,6 +1900,10 @@ struct testcase testcases[] = { test_verify_stripe_metadata_be_ver_mismatch, EC_BACKEND_SHSS, CHKSUM_CRC32, .skip = false}, + {"test_verify_stripe_metadata_frag_idx_invalid", + test_verify_stripe_metadata_frag_idx_invalid, + EC_BACKEND_SHSS, CHKSUM_CRC32, + .skip = false}, // Internal RS Vand backend tests {"create_and_destroy_backend", test_create_and_destroy_backend, @@ -1923,6 +1965,10 @@ struct testcase testcases[] = { test_verify_stripe_metadata_be_ver_mismatch, EC_BACKEND_LIBERASURECODE_RS_VAND, CHKSUM_CRC32, .skip = false}, + {"test_verify_stripe_metadata_frag_idx_invalid", + test_verify_stripe_metadata_frag_idx_invalid, + EC_BACKEND_LIBERASURECODE_RS_VAND, CHKSUM_CRC32, + .skip = false}, { NULL, NULL, 0, 0, false }, };