netfilter: nf_tables: fix pointer math issue in nft_byteorder_eval()
commit c301f0981fdd3fd1ffac6836b423c4d7a8e0eb63 upstream. The problem is in nft_byteorder_eval() where we are iterating through a loop and writing to dst[0], dst[1], dst[2] and so on... On each iteration we are writing 8 bytes. But dst[] is an array of u32 so each element only has space for 4 bytes. That means that every iteration overwrites part of the previous element. I spotted this bug while reviewing commit caf3ef7468f7 ("netfilter: nf_tables: prevent OOB access in nft_byteorder_eval") which is a related issue. I think that the reason we have not detected this bug in testing is that most of time we only write one element. Fixes: ce1e7989d989 ("netfilter: nft_byteorder: provide 64bit le/be conversion") Signed-off-by: Dan Carpenter <dan.carpenter@linaro.org> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org> [Ajay: Modified to apply on v5.10.y] Signed-off-by: Ajay Kaher <ajay.kaher@broadcom.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
5a8d23b1f1
commit
7b249074a1
3 changed files with 6 additions and 5 deletions
|
@ -142,9 +142,9 @@ static inline u16 nft_reg_load16(const u32 *sreg)
|
|||
return *(u16 *)sreg;
|
||||
}
|
||||
|
||||
static inline void nft_reg_store64(u32 *dreg, u64 val)
|
||||
static inline void nft_reg_store64(u64 *dreg, u64 val)
|
||||
{
|
||||
put_unaligned(val, (u64 *)dreg);
|
||||
put_unaligned(val, dreg);
|
||||
}
|
||||
|
||||
static inline u64 nft_reg_load64(const u32 *sreg)
|
||||
|
|
|
@ -38,20 +38,21 @@ void nft_byteorder_eval(const struct nft_expr *expr,
|
|||
|
||||
switch (priv->size) {
|
||||
case 8: {
|
||||
u64 *dst64 = (void *)dst;
|
||||
u64 src64;
|
||||
|
||||
switch (priv->op) {
|
||||
case NFT_BYTEORDER_NTOH:
|
||||
for (i = 0; i < priv->len / 8; i++) {
|
||||
src64 = nft_reg_load64(&src[i]);
|
||||
nft_reg_store64(&dst[i], be64_to_cpu(src64));
|
||||
nft_reg_store64(&dst64[i], be64_to_cpu(src64));
|
||||
}
|
||||
break;
|
||||
case NFT_BYTEORDER_HTON:
|
||||
for (i = 0; i < priv->len / 8; i++) {
|
||||
src64 = (__force __u64)
|
||||
cpu_to_be64(nft_reg_load64(&src[i]));
|
||||
nft_reg_store64(&dst[i], src64);
|
||||
nft_reg_store64(&dst64[i], src64);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -63,7 +63,7 @@ nft_meta_get_eval_time(enum nft_meta_keys key,
|
|||
{
|
||||
switch (key) {
|
||||
case NFT_META_TIME_NS:
|
||||
nft_reg_store64(dest, ktime_get_real_ns());
|
||||
nft_reg_store64((u64 *)dest, ktime_get_real_ns());
|
||||
break;
|
||||
case NFT_META_TIME_DAY:
|
||||
nft_reg_store8(dest, nft_meta_weekday());
|
||||
|
|
Loading…
Add table
Reference in a new issue