Skip to content

Commit 95c2027

Browse files
amirvdavem330
authored andcommitted
net/sched: pedit: make sure that offset is valid
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 <amir@vadai.me> Signed-off-by: David S. Miller <davem@davemloft.net>
1 parent 2dbb4c0 commit 95c2027

File tree

1 file changed

+20
-4
lines changed

1 file changed

+20
-4
lines changed

net/sched/act_pedit.c

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,17 @@ static void tcf_pedit_cleanup(struct tc_action *a, int bind)
108108
kfree(keys);
109109
}
110110

111+
static bool offset_valid(struct sk_buff *skb, int offset)
112+
{
113+
if (offset > 0 && offset > skb->len)
114+
return false;
115+
116+
if (offset < 0 && -offset > skb_headroom(skb))
117+
return false;
118+
119+
return true;
120+
}
121+
111122
static int tcf_pedit(struct sk_buff *skb, const struct tc_action *a,
112123
struct tcf_result *res)
113124
{
@@ -134,6 +145,11 @@ static int tcf_pedit(struct sk_buff *skb, const struct tc_action *a,
134145
if (tkey->offmask) {
135146
char *d, _d;
136147

148+
if (!offset_valid(skb, off + tkey->at)) {
149+
pr_info("tc filter pedit 'at' offset %d out of bounds\n",
150+
off + tkey->at);
151+
goto bad;
152+
}
137153
d = skb_header_pointer(skb, off + tkey->at, 1,
138154
&_d);
139155
if (!d)
@@ -146,10 +162,10 @@ static int tcf_pedit(struct sk_buff *skb, const struct tc_action *a,
146162
" offset must be on 32 bit boundaries\n");
147163
goto bad;
148164
}
149-
if (offset > 0 && offset > skb->len) {
150-
pr_info("tc filter pedit"
151-
" offset %d can't exceed pkt length %d\n",
152-
offset, skb->len);
165+
166+
if (!offset_valid(skb, off + offset)) {
167+
pr_info("tc filter pedit offset %d out of bounds\n",
168+
offset);
153169
goto bad;
154170
}
155171

0 commit comments

Comments
 (0)