Avoid UB in raid_gen memcpy when output aliases input with nd == 1

This commit is contained in:
Andrea Mazzoleni 2026-08-24 21:32:35 +02:00
parent 88442cb10c
commit 453fb20d83
6 changed files with 46 additions and 24 deletions

View file

@ -317,7 +317,8 @@ static __always_inline void raid_gen3_avx2ext_gen(int nd, size_t size, void **vv
/* special case with only one data disk */
if (l == 0) {
for (i = 0; i < 3; ++i)
memcpy(v[1 + i], v[0], size);
if (v[1 + i] != v[0])
memcpy(v[1 + i], v[0], size);
return;
}
@ -574,7 +575,8 @@ static __always_inline void raid_gen4_avx2ext_gen(int nd, size_t size, void **vv
/* special case with only one data disk */
if (l == 0) {
for (i = 0; i < 4; ++i)
memcpy(v[1 + i], v[0], size);
if (v[1 + i] != v[0])
memcpy(v[1 + i], v[0], size);
return;
}
@ -736,7 +738,8 @@ static __always_inline void raid_genX_avx2ext(int nd, size_t size, void **vv, in
/* special case with only one data disk */
if (l == 0) {
for (d = 0; d < np; ++d)
memcpy(v[1 + d], v[0], size);
if (v[1 + d] != v[0])
memcpy(v[1 + d], v[0], size);
return;
}

View file

@ -57,8 +57,10 @@ void raid_gen2_avx512bw(int nd, size_t size, void **vv)
int d;
if (nd == 1) {
memcpy(v[1], v[0], size);
memcpy(v[2], v[0], size);
if (v[1] != v[0])
memcpy(v[1], v[0], size);
if (v[2] != v[0])
memcpy(v[2], v[0], size);
return;
}
@ -281,9 +283,12 @@ void raid_gen3_avx512bw(int nd, size_t size, void **vv)
int d;
if (nd == 1) {
memcpy(v[1], v[0], size);
memcpy(v[2], v[0], size);
memcpy(v[3], v[0], size);
if (v[1] != v[0])
memcpy(v[1], v[0], size);
if (v[2] != v[0])
memcpy(v[2], v[0], size);
if (v[3] != v[0])
memcpy(v[3], v[0], size);
return;
}
@ -450,7 +455,8 @@ static __always_inline void raid_genX_avx512bw(int nd, size_t size, void **vv, i
if (nd == 1) {
for (d = 0; d < np; ++d)
memcpy(v[1 + d], v[0], size);
if (v[1 + d] != v[0])
memcpy(v[1 + d], v[0], size);
return;
}

View file

@ -18,7 +18,8 @@ static __always_inline void raid_genX_avx2gfni_raid(int nd, size_t size, void **
if (nd == 1) {
for (d = 0; d < np; ++d)
memcpy(v[1 + d], v[0], size);
if (v[1 + d] != v[0])
memcpy(v[1 + d], v[0], size);
return;
}
@ -129,7 +130,8 @@ static __always_inline void raid_genX_avx512gfni_raid(int nd, size_t size, void
if (nd == 1) {
for (d = 0; d < np; ++d)
memcpy(v[1 + d], v[0], size);
if (v[1 + d] != v[0])
memcpy(v[1 + d], v[0], size);
return;
}
@ -212,7 +214,8 @@ static __always_inline void raid_genX_avx2gfni_aes(int nd, size_t size, void **v
if (nd == 1) {
for (d = 0; d < np; ++d)
memcpy(v[1 + d], v[0], size);
if (v[1 + d] != v[0])
memcpy(v[1 + d], v[0], size);
return;
}
@ -330,7 +333,8 @@ static __always_inline void raid_genX_avx512gfni_aes(int nd, size_t size, void *
if (nd == 1) {
for (d = 0; d < np; ++d)
memcpy(v[1 + d], v[0], size);
if (v[1 + d] != v[0])
memcpy(v[1 + d], v[0], size);
return;
}
@ -779,7 +783,7 @@ static __always_inline void raid_recX_avx512gfni_raid(int nr, int *id, int *ip,
raid_avx_end();
}
static __always_inline void raid_recX_avx2gfni_aes(int nr, int *id, int *ip, int nd, size_t size, void **vv)
{
uint8_t **v = (uint8_t **)vv;

View file

@ -250,7 +250,8 @@ static __always_inline void raid_genX_neon(int nd, size_t size, void **vv, int n
/* special case with only one data disk */
if (l == 0) {
for (d = 0; d < np; ++d)
memcpy(v[1 + d], v[0], size);
if (v[1 + d] != v[0])
memcpy(v[1 + d], v[0], size);
return;
}

View file

@ -244,7 +244,8 @@ static __always_inline void raid_genX_neon32(int nd, size_t size,
/* special case with only one data disk */
if (l == 0) {
for (d = 0; d < np; ++d)
memcpy(v[1 + d], v[0], size);
if (v[1 + d] != v[0])
memcpy(v[1 + d], v[0], size);
return;
}

View file

@ -26,7 +26,8 @@ static __always_inline void raid_gen3_ssse3_gen(int nd, size_t size, void **vv,
/* special case with only one data disk */
if (l == 0) {
for (i = 0; i < 3; ++i)
memcpy(v[1 + i], v[0], size);
if (v[1 + i] != v[0])
memcpy(v[1 + i], v[0], size);
return;
}
@ -131,7 +132,8 @@ static __always_inline void raid_gen4_ssse3_gen(int nd, size_t size, void **vv,
/* special case with only one data disk */
if (l == 0) {
for (i = 0; i < 4; ++i)
memcpy(v[1 + i], v[0], size);
if (v[1 + i] != v[0])
memcpy(v[1 + i], v[0], size);
return;
}
@ -257,7 +259,8 @@ void raid_gen5_ssse3_raid(int nd, size_t size, void **vv)
/* special case with only one data disk */
if (l == 0) {
for (i = 0; i < 5; ++i)
memcpy(v[1 + i], v[0], size);
if (v[1 + i] != v[0])
memcpy(v[1 + i], v[0], size);
return;
}
@ -394,7 +397,8 @@ void raid_gen6_ssse3_raid(int nd, size_t size, void **vv)
/* special case with only one data disk */
if (l == 0) {
for (i = 0; i < 6; ++i)
memcpy(v[1 + i], v[0], size);
if (v[1 + i] != v[0])
memcpy(v[1 + i], v[0], size);
return;
}
@ -545,7 +549,8 @@ static __always_inline void raid_gen3_ssse3ext_gen(int nd, size_t size, void **v
/* special case with only one data disk */
if (l == 0) {
for (i = 0; i < 3; ++i)
memcpy(v[1 + i], v[0], size);
if (v[1 + i] != v[0])
memcpy(v[1 + i], v[0], size);
return;
}
@ -805,7 +810,8 @@ static __always_inline void raid_gen4_ssse3ext_gen(int nd, size_t size, void **v
/* special case with only one data disk */
if (l == 0) {
for (i = 0; i < 4; ++i)
memcpy(v[1 + i], v[0], size);
if (v[1 + i] != v[0])
memcpy(v[1 + i], v[0], size);
return;
}
@ -995,7 +1001,8 @@ static __always_inline void raid_genX_ssse3ext(int nd, size_t size, void **vv, i
/* special case with only one data disk */
if (l == 0) {
for (d = 0; d < np; ++d)
memcpy(v[1 + d], v[0], size);
if (v[1 + d] != v[0])
memcpy(v[1 + d], v[0], size);
return;
}
@ -1773,7 +1780,7 @@ static __always_inline void raid_recX_ssse3(int nr, int *id, int *ip, int nd, si
*
* Process two 16-byte blocks per iteration, grouping equal operations across
* both lanes to expose instruction-level parallelism.
*
*
* A four-way 64-byte unroll was tested but is slower than this two-way 32-byte
* implementation.
*/