Skip to content

Commit cafdc14

Browse files
committed
xor codes: Fail if there were >= hd failures
Previously we'd either silently return corrupted data, or seg fault. Closes-Bug: #2118949 Change-Id: I3b176fc331be7ed2168ddc11aeec5a2d7ffe6f13
1 parent 303e146 commit cafdc14

File tree

3 files changed

+52
-0
lines changed

3 files changed

+52
-0
lines changed

src/builtin/xor_codes/xor_code.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ failure_pattern_t get_failure_pattern(xor_code_t *code_desc, int *missing_idxs)
8686
failure_pattern_t pattern = FAIL_PATTERN_0D_0P;
8787

8888
while (missing_idxs[i] > -1) {
89+
num_failures++;
8990
if (num_failures >= code_desc->hd) {
9091
pattern = FAIL_PATTERN_GE_HD;
9192
}

src/builtin/xor_codes/xor_hd_code.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -370,6 +370,7 @@ int xor_hd_fragments_needed(xor_code_t *code_desc, int *fragments_to_reconstruct
370370
}
371371
case FAIL_PATTERN_GE_HD:
372372
default:
373+
ret = -1;
373374
break;
374375
}
375376
}
@@ -646,6 +647,7 @@ int xor_hd_decode(xor_code_t *code_desc, char **data, char **parity, int *missin
646647
break;
647648
case FAIL_PATTERN_GE_HD:
648649
default:
650+
ret = -1;
649651
break;
650652
}
651653

test/liberasurecode_test.c

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1620,6 +1620,54 @@ static void test_flat_xor_hd3_init_failure(void)
16201620
}
16211621
}
16221622

1623+
static void test_flat_xor_too_many_failures(void)
1624+
{
1625+
int desc = -1;
1626+
int orig_data_size = 1024 * 1024;
1627+
char *orig_data = NULL;
1628+
char **encoded_data = NULL, **encoded_parity = NULL;
1629+
uint64_t encoded_fragment_len = 0;
1630+
uint64_t decoded_data_len = 0;
1631+
char *decoded_data = NULL;
1632+
char **avail_frags = NULL;
1633+
int num_avail_frags = 0;
1634+
int rc = -1;
1635+
struct ec_args bad_args[] = {
1636+
{.k = 5, .m = 5, .hd=3},
1637+
{.k = 5, .m = 5, .hd=4},
1638+
};
1639+
int *skip = create_skips_array(bad_args,-1);
1640+
skip[0] = skip[1] = skip[2] = skip[3] = 1;
1641+
1642+
for (int i = 0; i < sizeof(bad_args)/sizeof(bad_args[0]); ++i) {
1643+
desc = liberasurecode_instance_create(
1644+
EC_BACKEND_FLAT_XOR_HD, &bad_args[i]);
1645+
assert(desc > 0);
1646+
orig_data = create_buffer(orig_data_size, 'x');
1647+
assert(orig_data != NULL);
1648+
rc = liberasurecode_encode(desc, orig_data, orig_data_size,
1649+
&encoded_data, &encoded_parity, &encoded_fragment_len);
1650+
assert(0 == rc);
1651+
1652+
num_avail_frags = create_frags_array(&avail_frags, encoded_data,
1653+
encoded_parity, &bad_args[i], skip);
1654+
assert(num_avail_frags > 0);
1655+
rc = liberasurecode_decode(desc, avail_frags, num_avail_frags,
1656+
encoded_fragment_len, 1,
1657+
&decoded_data, &decoded_data_len);
1658+
assert(-1 == rc);
1659+
assert(decoded_data == NULL);
1660+
assert(decoded_data_len == 0);
1661+
rc = liberasurecode_encode_cleanup(desc, encoded_data, encoded_parity);
1662+
assert(rc == 0);
1663+
1664+
assert(0 == liberasurecode_instance_destroy(desc));
1665+
free(orig_data);
1666+
free(avail_frags);
1667+
}
1668+
free(skip);
1669+
}
1670+
16231671
static void test_simple_encode_decode(const ec_backend_id_t be_id,
16241672
struct ec_args *args)
16251673
{
@@ -1955,6 +2003,7 @@ struct testcase testcases[] = {
19552003
// Flat XOR backend tests
19562004
TEST_SUITE(EC_BACKEND_FLAT_XOR_HD),
19572005
TEST({.no_args = test_flat_xor_hd3_init_failure}, EC_BACKENDS_MAX, 0),
2006+
TEST({.no_args = test_flat_xor_too_many_failures}, EC_BACKENDS_MAX, 0),
19582007
// Jerasure RS Vand backend tests
19592008
TEST_SUITE(EC_BACKEND_JERASURE_RS_VAND),
19602009
TEST({.no_args = test_jerasure_rs_vand_simple_encode_decode_over32}, EC_BACKENDS_MAX, 0),

0 commit comments

Comments
 (0)