netfilter: nf_tables: fix pointer math issue in nft_byteorder_eval()
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 commitcaf3ef7468
("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:ce1e7989d9
("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>
This commit is contained in:
parent
a44af08e3d
commit
c301f0981f
@ -178,9 +178,9 @@ static inline __be32 nft_reg_load_be32(const u32 *sreg)
|
||||
return *(__force __be32 *)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,13 +38,14 @@ 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],
|
||||
nft_reg_store64(&dst64[i],
|
||||
be64_to_cpu((__force __be64)src64));
|
||||
}
|
||||
break;
|
||||
@ -52,7 +53,7 @@ void nft_byteorder_eval(const struct nft_expr *expr,
|
||||
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…
Reference in New Issue
Block a user