+ if (offset > 0 && offset > skb->len) offset > skb->len is enough?
On Mon, Nov 28, 2016 at 6:56 PM, Amir Vadai <a...@vadai.me> wrote: > Add a validation function to make sure offset is valid: > 1. Not below skb head (could happen when offset is negative). > 2. Validate both 'offset' and 'at'. > > Signed-off-by: Amir Vadai <a...@vadai.me> > --- > Hi Dave, > > Please pull to -stable branches. > > Changes from V0: > - Add a validation to the 'at' value (this is used as an offset too) > - Instead of validating the output of skb_header_pointer(), make sure that the > offset is good before calling it. > > Thanks, > Amir > net/sched/act_pedit.c | 24 ++++++++++++++++++++---- > 1 file changed, 20 insertions(+), 4 deletions(-) > > diff --git a/net/sched/act_pedit.c b/net/sched/act_pedit.c > index b54d56d4959b..cf9b2fe8eac6 100644 > --- a/net/sched/act_pedit.c > +++ b/net/sched/act_pedit.c > @@ -108,6 +108,17 @@ static void tcf_pedit_cleanup(struct tc_action *a, int > bind) > kfree(keys); > } > > +static bool offset_valid(struct sk_buff *skb, int offset) > +{ > + if (offset > 0 && offset > skb->len) > + return false; > + > + if (offset < 0 && -offset > skb_headroom(skb)) > + return false; > + > + return true; > +} > + > static int tcf_pedit(struct sk_buff *skb, const struct tc_action *a, > struct tcf_result *res) > { > @@ -134,6 +145,11 @@ static int tcf_pedit(struct sk_buff *skb, const struct > tc_action *a, > if (tkey->offmask) { > char *d, _d; > > + if (!offset_valid(skb, off + tkey->at)) { > + pr_info("tc filter pedit 'at' offset > %d out of bounds\n", > + off + tkey->at); > + goto bad; > + } > d = skb_header_pointer(skb, off + tkey->at, 1, > &_d); > if (!d) > @@ -146,10 +162,10 @@ static int tcf_pedit(struct sk_buff *skb, const struct > tc_action *a, > " offset must be on 32 bit > boundaries\n"); > goto bad; > } > - if (offset > 0 && offset > skb->len) { > - pr_info("tc filter pedit" > - " offset %d can't exceed pkt length > %d\n", > - offset, skb->len); > + > + if (!offset_valid(skb, off + offset)) { > + pr_info("tc filter pedit offset %d out of > bounds\n", > + offset); > goto bad; > } > > -- > 2.10.2 >