Skip to content

Commit

Permalink
net/sched: act_ipt: zero skb->cb before calling target
Browse files Browse the repository at this point in the history
xtables relies on skb being owned by ip stack, i.e. with ipv4
check in place skb->cb is supposed to be IPCB.

I don't see an immediate problem (REJECT target cannot be used anymore
now that PRE/POSTROUTING hook validation has been fixed), but better be
safe than sorry.

A much better patch would be to either mark act_ipt as
"depends on BROKEN" or remove it altogether. I plan to do this
for -next in the near future.

This tc extension is broken in the sense that tc lacks an
equivalent of NF_STOLEN verdict.

With NF_STOLEN, target function takes complete ownership of skb, caller
cannot dereference it anymore.

ACT_STOLEN cannot be used for this: it has a different meaning, caller
is allowed to dereference the skb.

At this time NF_STOLEN won't be returned by any targets as far as I can
see, but this may change in the future.

It might be possible to work around this via list of allowed
target extensions known to only return DROP or ACCEPT verdicts, but this
is error prone/fragile.

Existing selftest only validates xt_LOG and act_ipt is restricted
to ipv4 so I don't think this action is used widely.

Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Signed-off-by: Florian Westphal <[email protected]>
Reviewed-by: Simon Horman <[email protected]>
Acked-by: Jamal Hadi Salim <[email protected]>
Signed-off-by: Paolo Abeni <[email protected]>
  • Loading branch information
Florian Westphal authored and Paolo Abeni committed Jun 29, 2023
1 parent b2dc32d commit 93d75d4
Showing 1 changed file with 10 additions and 0 deletions.
10 changes: 10 additions & 0 deletions net/sched/act_ipt.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#include <linux/tc_act/tc_ipt.h>
#include <net/tc_act/tc_ipt.h>
#include <net/tc_wrapper.h>
#include <net/ip.h>

#include <linux/netfilter_ipv4/ip_tables.h>

Expand Down Expand Up @@ -254,6 +255,7 @@ TC_INDIRECT_SCOPE int tcf_ipt_act(struct sk_buff *skb,
const struct tc_action *a,
struct tcf_result *res)
{
char saved_cb[sizeof_field(struct sk_buff, cb)];
int ret = 0, result = 0;
struct tcf_ipt *ipt = to_ipt(a);
struct xt_action_param par;
Expand All @@ -280,6 +282,8 @@ TC_INDIRECT_SCOPE int tcf_ipt_act(struct sk_buff *skb,
state.out = skb->dev;
}

memcpy(saved_cb, skb->cb, sizeof(saved_cb));

spin_lock(&ipt->tcf_lock);

tcf_lastuse_update(&ipt->tcf_tm);
Expand All @@ -292,6 +296,9 @@ TC_INDIRECT_SCOPE int tcf_ipt_act(struct sk_buff *skb,
par.state = &state;
par.target = ipt->tcfi_t->u.kernel.target;
par.targinfo = ipt->tcfi_t->data;

memset(IPCB(skb), 0, sizeof(struct inet_skb_parm));

ret = par.target->target(skb, &par);

switch (ret) {
Expand All @@ -312,6 +319,9 @@ TC_INDIRECT_SCOPE int tcf_ipt_act(struct sk_buff *skb,
break;
}
spin_unlock(&ipt->tcf_lock);

memcpy(skb->cb, saved_cb, sizeof(skb->cb));

return result;

}
Expand Down

0 comments on commit 93d75d4

Please sign in to comment.