File tree Expand file tree Collapse file tree 2 files changed +26
-1
lines changed Expand file tree Collapse file tree 2 files changed +26
-1
lines changed Original file line number Diff line number Diff line change @@ -2886,6 +2886,29 @@ static inline void skb_reset_transport_header(struct sk_buff *skb)
2886
2886
skb -> transport_header = skb -> data - skb -> head ;
2887
2887
}
2888
2888
2889
+ /**
2890
+ * skb_reset_transport_header_careful - conditionally reset transport header
2891
+ * @skb: buffer to alter
2892
+ *
2893
+ * Hardened version of skb_reset_transport_header().
2894
+ *
2895
+ * Returns: true if the operation was a success.
2896
+ */
2897
+ static inline bool __must_check
2898
+ skb_reset_transport_header_careful (struct sk_buff * skb )
2899
+ {
2900
+ long offset = skb -> data - skb -> head ;
2901
+
2902
+ if (unlikely (offset != (typeof (skb -> transport_header ))offset ))
2903
+ return false;
2904
+
2905
+ if (unlikely (offset == (typeof (skb -> transport_header ))~0U ))
2906
+ return false;
2907
+
2908
+ skb -> transport_header = offset ;
2909
+ return true;
2910
+ }
2911
+
2889
2912
static inline void skb_set_transport_header (struct sk_buff * skb ,
2890
2913
const int offset )
2891
2914
{
Original file line number Diff line number Diff line change @@ -150,7 +150,9 @@ static struct sk_buff *ipv6_gso_segment(struct sk_buff *skb,
150
150
151
151
ops = rcu_dereference (inet6_offloads [proto ]);
152
152
if (likely (ops && ops -> callbacks .gso_segment )) {
153
- skb_reset_transport_header (skb );
153
+ if (!skb_reset_transport_header_careful (skb ))
154
+ goto out ;
155
+
154
156
segs = ops -> callbacks .gso_segment (skb , features );
155
157
if (!segs )
156
158
skb -> network_header = skb_mac_header (skb ) + nhoff - skb -> head ;
You can’t perform that action at this time.
0 commit comments