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 @@ -3002,6 +3002,29 @@ static inline void skb_reset_transport_header(struct sk_buff *skb)
30023002 skb -> transport_header = skb -> data - skb -> head ;
30033003}
30043004
3005+ /**
3006+ * skb_reset_transport_header_careful - conditionally reset transport header
3007+ * @skb: buffer to alter
3008+ *
3009+ * Hardened version of skb_reset_transport_header().
3010+ *
3011+ * Returns: true if the operation was a success.
3012+ */
3013+ static inline bool __must_check
3014+ skb_reset_transport_header_careful (struct sk_buff * skb )
3015+ {
3016+ long offset = skb -> data - skb -> head ;
3017+
3018+ if (unlikely (offset != (typeof (skb -> transport_header ))offset ))
3019+ return false;
3020+
3021+ if (unlikely (offset == (typeof (skb -> transport_header ))~0U ))
3022+ return false;
3023+
3024+ skb -> transport_header = offset ;
3025+ return true;
3026+ }
3027+
30053028static inline void skb_set_transport_header (struct sk_buff * skb ,
30063029 const int offset )
30073030{
Original file line number Diff line number Diff line change @@ -148,7 +148,9 @@ static struct sk_buff *ipv6_gso_segment(struct sk_buff *skb,
148148
149149 ops = rcu_dereference (inet6_offloads [proto ]);
150150 if (likely (ops && ops -> callbacks .gso_segment )) {
151- skb_reset_transport_header (skb );
151+ if (!skb_reset_transport_header_careful (skb ))
152+ goto out ;
153+
152154 segs = ops -> callbacks .gso_segment (skb , features );
153155 if (!segs )
154156 skb -> network_header = skb_mac_header (skb ) + nhoff - skb -> head ;
You can’t perform that action at this time.
0 commit comments