From: Jakub Kicinski <jakub.kicinski@xxxxxxxxxxxxx> Date: Mon, 4 Nov 2019 15:36:57 -0800 > sk_msg_trim() tries to only update curr pointer if it falls into > the trimmed region. The logic, however, does not take into the > account pointer wrapping that sk_msg_iter_var_prev() does nor > (as John points out) the fact that msg->sg is a ring buffer. > > This means that when the message was trimmed completely, the new > curr pointer would have the value of MAX_MSG_FRAGS - 1, which is > neither smaller than any other value, nor would it actually be > correct. > > Special case the trimming to 0 length a little bit and rework > the comparison between curr and end to take into account wrapping. > > This bug caused the TLS code to not copy all of the message, if > zero copy filled in fewer sg entries than memcopy would need. > > Big thanks to Alexander Potapenko for the non-KMSAN reproducer. > > v2: > - take into account that msg->sg is a ring buffer (John). > > Link: https://lore.kernel.org/netdev/20191030160542.30295-1-jakub.kicinski@xxxxxxxxxxxxx/ (v1) > > Fixes: d829e9c4112b ("tls: convert to generic sk_msg interface") > Reported-by: syzbot+f8495bff23a879a6d0bd@xxxxxxxxxxxxxxxxxxxxxxxxx > Reported-by: syzbot+6f50c99e8f6194bf363f@xxxxxxxxxxxxxxxxxxxxxxxxx > Co-developed-by: John Fastabend <john.fastabend@xxxxxxxxx> > Signed-off-by: Jakub Kicinski <jakub.kicinski@xxxxxxxxxxxxx> Applied and queued up for -stable, thanks Jakub.