> -----Original Message----- > From: Paolo Abeni <pab...@redhat.com> > Sent: Tuesday, January 19, 2021 4:31 AM > To: netdev@vger.kernel.org > Cc: David S . Miller <da...@davemloft.net>; Jakub Kicinski > <k...@kernel.org>; Alexander Duyck <alexanderdu...@fb.com>; Xin Long > <lucien....@gmail.com> > Subject: [PATCH net-next] net: fix GSO for SG-enabled devices. > > The commit dbd50f238dec ("net: move the hsize check to the else block in > skb_segment") introduced a data corruption for devices supporting scatter- > gather. > > The problem boils down to signed/unsigned comparison given unexpected > results: if signed 'hsize' is negative, it will be considered greater than a > positive 'len', which is unsigned. > > This commit addresses the issue explicitly casting 'len' to a signed integer, > so > that the comparison gives the correct result. > > Bisected-by: Matthieu Baerts <matthieu.bae...@tessares.net> > Fixes: dbd50f238dec ("net: move the hsize check to the else block in > skb_segment") > Signed-off-by: Paolo Abeni <pab...@redhat.com> > --- > note: a possible more readable alternative would be moving the > if (hsize < 0) > > before 'if (hsize > len)', but that was explicitly discouraged in a previous > iteration of the blamed commit to save a comparison, so I opted to preserve > that optimization.
I would say it is probably better to just moving the "hsize < 0" check. What I had suggested was a minor optimization and it hadn't occurred to me that this is a signed vs unsigned comparison. > --- > net/core/skbuff.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > > diff --git a/net/core/skbuff.c b/net/core/skbuff.c index > e835193cabcc3..27f69c0bd8393 100644 > --- a/net/core/skbuff.c > +++ b/net/core/skbuff.c > @@ -3938,7 +3938,7 @@ struct sk_buff *skb_segment(struct sk_buff > *head_skb, > skb_release_head_state(nskb); > __skb_push(nskb, doffset); > } else { > - if (hsize > len || !sg) > + if (hsize > (int)len || !sg) > hsize = len; > else if (hsize < 0) > hsize = 0;