Harden public RAID API argument validation

This commit is contained in:
Andrea Mazzoleni 2026-08-24 14:05:56 +02:00
parent ae703ce68c
commit d4184b9aee
3 changed files with 83 additions and 18 deletions

View file

@ -113,10 +113,20 @@ int raid_check(int nr, int *ir, int nd, int np, size_t size, void **v)
/* enforce limit on size */
BUG_ON(size % 64 != 0);
/* enforce limit on number of failures */
BUG_ON(nr >= np); /* >= because we check with extra parity */
/* enforce limit on number of data blocks */
BUG_ON(nd < 1 || nd > RAID_DATA_MAX);
/* enforce limit on number of parity blocks */
BUG_ON(np < 1);
BUG_ON(np > RAID_PARITY_MAX || (raid_mode_active == RAID_MODE_VANDERMONDE_RAID && np > 3));
/* enforce limit on number of failures */
BUG_ON(nr < 0 || nr >= np); /* >= because we check with extra parity */
/* enforce valid vectors */
BUG_ON(v == 0);
BUG_ON(nr > 0 && ir == 0);
/* enforce order in index vector */
BUG_ON(nr >= 2 && ir[0] >= ir[1]);
BUG_ON(nr >= 3 && ir[1] >= ir[2]);
@ -125,6 +135,7 @@ int raid_check(int nr, int *ir, int nd, int np, size_t size, void **v)
BUG_ON(nr >= 6 && ir[4] >= ir[5]);
/* enforce limit on index vector */
BUG_ON(nr > 0 && ir[0] < 0);
BUG_ON(nr > 0 && ir[nr - 1] >= nd + np);
/* count failed data disk */
@ -153,6 +164,20 @@ int raid_scan(int *ir, int nd, int np, size_t size, void **v)
{
int r;
/* enforce limit on size */
BUG_ON(size % 64 != 0);
/* enforce limit on number of data blocks */
BUG_ON(nd < 1 || nd > RAID_DATA_MAX);
/* enforce limit on number of parity blocks */
BUG_ON(np < 0);
BUG_ON(np > RAID_PARITY_MAX || (raid_mode_active == RAID_MODE_VANDERMONDE_RAID && np > 3));
/* enforce valid vectors */
BUG_ON(v == 0);
BUG_ON(np > 1 && ir == 0);
/* check the special case of no failure */
if (np != 0 && raid_check(0, 0, nd, np, size, v) == 0)
return 0;

View file

@ -78,10 +78,16 @@ void raid_gen(int nd, int np, size_t size, void **v)
/* enforce limit on size */
BUG_ON(size % 64 != 0);
/* enforce limit on number of failures */
/* enforce limit on number of data blocks */
BUG_ON(nd < 1 || nd > RAID_DATA_MAX);
/* enforce limit on number of parity blocks */
BUG_ON(np < 1);
BUG_ON(np > RAID_PARITY_MAX || (raid_mode_active == RAID_MODE_VANDERMONDE_RAID && np > 3));
/* enforce valid vector */
BUG_ON(v == 0);
BUG_ON(raid_gen_ptr[np - 1] == 0);
raid_gen_ptr[np - 1](nd, size, v);
}
@ -103,10 +109,20 @@ void raid_rec(int nr, int *ir, int nd, int np, size_t size, void **v)
/* enforce limit on size */
BUG_ON(size % 64 != 0);
/* enforce limit on number of failures */
BUG_ON(nr > np);
/* enforce limit on number of data blocks */
BUG_ON(nd < 1 || nd > RAID_DATA_MAX);
/* enforce limit on number of parity blocks */
BUG_ON(np < 1);
BUG_ON(np > RAID_PARITY_MAX || (raid_mode_active == RAID_MODE_VANDERMONDE_RAID && np > 3));
/* enforce limit on number of failures */
BUG_ON(nr < 0 || nr > np);
/* enforce valid vectors */
BUG_ON(v == 0);
BUG_ON(nr > 0 && ir == 0);
/* enforce order in index vector */
BUG_ON(nr >= 2 && ir[0] >= ir[1]);
BUG_ON(nr >= 3 && ir[1] >= ir[2]);
@ -115,6 +131,7 @@ void raid_rec(int nr, int *ir, int nd, int np, size_t size, void **v)
BUG_ON(nr >= 6 && ir[4] >= ir[5]);
/* enforce limit on index vector */
BUG_ON(nr > 0 && ir[0] < 0);
BUG_ON(nr > 0 && ir[nr - 1] >= nd + np);
/* count the number of data blocks to recover */
@ -150,6 +167,7 @@ void raid_rec(int nr, int *ir, int nd, int np, size_t size, void **v)
* Recover the nrd data blocks specified in ir[],
* using the first nrd parity in ip[] for recovering
*/
BUG_ON(raid_rec_ptr[nrd - 1] == 0);
raid_rec_ptr[nrd - 1](nrd, ir, ip, nd, size, v);
}
@ -163,10 +181,18 @@ void raid_data(int nr, int *id, int *ip, int nd, size_t size, void **v)
/* enforce limit on size */
BUG_ON(size % 64 != 0);
/* enforce limit on number of data blocks */
BUG_ON(nd < 1 || nd > RAID_DATA_MAX);
/* enforce limit on number of failures */
BUG_ON(nr > nd);
BUG_ON(nr < 0 || nr > nd);
BUG_ON(nr > RAID_PARITY_MAX);
/* enforce valid vectors */
BUG_ON(v == 0);
BUG_ON(nr > 0 && id == 0);
BUG_ON(nr > 0 && ip == 0);
/* enforce order in index vector for data */
BUG_ON(nr >= 2 && id[0] >= id[1]);
BUG_ON(nr >= 3 && id[1] >= id[2]);
@ -175,6 +201,7 @@ void raid_data(int nr, int *id, int *ip, int nd, size_t size, void **v)
BUG_ON(nr >= 6 && id[4] >= id[5]);
/* enforce limit on index vector for data */
BUG_ON(nr > 0 && id[0] < 0);
BUG_ON(nr > 0 && id[nr - 1] >= nd);
/* enforce order in index vector for parity */
@ -185,6 +212,7 @@ void raid_data(int nr, int *id, int *ip, int nd, size_t size, void **v)
BUG_ON(nr >= 6 && ip[4] >= ip[5]);
/* enforce limit on index vector for parity */
BUG_ON(nr > 0 && ip[0] < 0);
BUG_ON(nr > 0 && (ip[nr - 1] >= RAID_PARITY_MAX || (raid_mode_active == RAID_MODE_VANDERMONDE_RAID && ip[nr - 1] >= 3)));
/* if failed data is present */

View file

@ -198,8 +198,9 @@ void raid_zero(void *zero);
*
* Each parity block allows to recover one data block.
*
* @nd Number of data blocks.
* @np Number of parity blocks to compute.
* @nd Number of data blocks. It must be between 1 and RAID_DATA_MAX.
* @np Number of parity blocks to compute. It must be between 1 and
* RAID_PARITY_MAX. RAID_MODE_VANDERMONDE_RAID supports at most 3.
* @size Size of the blocks pointed to by @v. It must be a multiple of 64.
* @v Vector of pointers to the blocks of data and parity.
* It has (@nd + @np) elements. The starting elements are the blocks for
@ -230,13 +231,16 @@ void raid_gen(int nd, int np, size_t size, void **v);
* This happens even in the case you have more parity blocks than needed,
* and some form of integrity verification would be possible.
*
* @nr Number of failed data and parity blocks to recover.
* @nr Number of failed data and parity blocks to recover. It must be
* between 0 and @np.
* @ir[] Vector of @nr indexes of the failed data and parity blocks.
* The indexes start from 0. They must be in order.
* All indexes must be nonnegative and smaller than @nd + @np.
* The first parity is represented with value @nd, the second with value
* @nd + 1, just like positions in the @v vector.
* @nd Number of data blocks.
* @np Number of parity blocks.
* @nd Number of data blocks. It must be between 1 and RAID_DATA_MAX.
* @np Number of parity blocks. It must be between 1 and RAID_PARITY_MAX.
* RAID_MODE_VANDERMONDE_RAID supports at most 3.
* @size Size of the blocks pointed by @v. It must be a multiple of 64.
* @v Vector of pointers to the blocks of data and parity.
* It has (@nd + @np) elements. The starting elements are the blocks
@ -253,12 +257,16 @@ void raid_rec(int nr, int *ir, int nd, int np, size_t size, void **v);
* This function recovers all the data blocks marked as bad in the @id vector.
* The parity blocks are not modified.
*
* @nr Number of failed data blocks to recover.
* @nr Number of failed data blocks to recover. It must be nonnegative,
* not greater than @nd, and not greater than RAID_PARITY_MAX.
* @id[] Vector of @nr indexes of the data blocks to recover.
* The indexes start from 0. They must be in order.
* All indexes must be nonnegative and smaller than @nd.
* @ip[] Vector of @nr indexes of the parity blocks to use for recovery.
* The indexes start from 0. They must be in order.
* @nd Number of data blocks.
* All indexes must be nonnegative and smaller than RAID_PARITY_MAX.
* In RAID_MODE_VANDERMONDE_RAID they must be smaller than 3.
* @nd Number of data blocks. It must be between 1 and RAID_DATA_MAX.
* @size Size of the blocks pointed to by @v. It must be a multiple of 64.
* @v Vector of pointers to the blocks of data and parity.
* It has (@nd + @ip[@nr - 1] + 1) elements. The starting elements are the
@ -281,13 +289,16 @@ void raid_data(int nr, int *id, int *ip, int nd, size_t size, void **v);
*
* No data or parity blocks are modified.
*
* @nr Number of failed data and parity blocks.
* @nr Number of failed data and parity blocks. It must be nonnegative and
* strictly smaller than @np.
* @ir[] Vector of @nr indexes of the failed data and parity blocks.
* The indexes start from 0. They must be in order.
* All indexes must be nonnegative and smaller than @nd + @np.
* The first parity is represented with value @nd, the second with value
* @nd + 1, just like positions in the @v vector.
* @nd Number of data blocks.
* @np Number of parity blocks.
* @nd Number of data blocks. It must be between 1 and RAID_DATA_MAX.
* @np Number of parity blocks. It must be between 1 and RAID_PARITY_MAX.
* RAID_MODE_VANDERMONDE_RAID supports at most 3.
* @size Size of the blocks pointed by @v. It must be a multiple of 64.
* @v Vector of pointers to the blocks of data and parity.
* It has (@nd + @np) elements. The starting elements are the blocks
@ -331,8 +342,9 @@ int raid_check(int nr, int *ir, int nd, int np, size_t size, void **v);
* The indexes start from 0 and they are in order.
* The first parity is represented with value @nd, the second with value
* @nd + 1, just like positions in the @v vector.
* @nd Number of data blocks.
* @np Number of parity blocks.
* @nd Number of data blocks. It must be between 1 and RAID_DATA_MAX.
* @np Number of parity blocks. It must be between 0 and RAID_PARITY_MAX.
* RAID_MODE_VANDERMONDE_RAID supports at most 3.
* @size Size of the blocks pointed by @v. It must be a multiple of 64.
* @v Vector of pointers to the blocks of data and parity.
* It has (@nd + @np) elements. The starting elements are the blocks