Skip to content

Commit e7fce92

Browse files
committed
netfilter: nf_tables: fix pointer math issue in nft_byteorder_eval()
JIRA: https://issues.redhat.com/browse/RHEL-21443 Upstream Status: commit c301f09 Conflicts: include/net/netfilter/nf_tables.h net/netfilter/nft_byteorder.c Context, we lack 7278b3c ("netfilter: nf_tables: add and use BE register load-store helpers"), which is a sparse-cleanup, not a functional fix. commit c301f09 Author: Dan Carpenter <dan.carpenter@linaro.org> Date: Fri Nov 3 09:42:51 2023 +0300 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 commit caf3ef7 ("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: ce1e798 ("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> Signed-off-by: Florian Westphal <fwestpha@redhat.com>
1 parent 0f3140d commit e7fce92

File tree

3 files changed

+7
-5
lines changed

3 files changed

+7
-5
lines changed

include/net/netfilter/nf_tables.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -150,9 +150,9 @@ static inline u16 nft_reg_load16(const u32 *sreg)
150150
return *(u16 *)sreg;
151151
}
152152

153-
static inline void nft_reg_store64(u32 *dreg, u64 val)
153+
static inline void nft_reg_store64(u64 *dreg, u64 val)
154154
{
155-
put_unaligned(val, (u64 *)dreg);
155+
put_unaligned(val, dreg);
156156
}
157157

158158
static inline u64 nft_reg_load64(const u32 *sreg)

net/netfilter/nft_byteorder.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,20 +38,22 @@ void nft_byteorder_eval(const struct nft_expr *expr,
3838

3939
switch (priv->size) {
4040
case 8: {
41+
u64 *dst64 = (void *)dst;
4142
u64 src64;
4243

4344
switch (priv->op) {
4445
case NFT_BYTEORDER_NTOH:
4546
for (i = 0; i < priv->len / 8; i++) {
4647
src64 = nft_reg_load64(&src[i]);
47-
nft_reg_store64(&dst[i], be64_to_cpu(src64));
48+
nft_reg_store64(&dst64[i],
49+
be64_to_cpu((__force __be64)src64));
4850
}
4951
break;
5052
case NFT_BYTEORDER_HTON:
5153
for (i = 0; i < priv->len / 8; i++) {
5254
src64 = (__force __u64)
5355
cpu_to_be64(nft_reg_load64(&src[i]));
54-
nft_reg_store64(&dst[i], src64);
56+
nft_reg_store64(&dst64[i], src64);
5557
}
5658
break;
5759
}

net/netfilter/nft_meta.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ nft_meta_get_eval_time(enum nft_meta_keys key,
6363
{
6464
switch (key) {
6565
case NFT_META_TIME_NS:
66-
nft_reg_store64(dest, ktime_get_real_ns());
66+
nft_reg_store64((u64 *)dest, ktime_get_real_ns());
6767
break;
6868
case NFT_META_TIME_DAY:
6969
nft_reg_store8(dest, nft_meta_weekday());

0 commit comments

Comments
 (0)