sock: fix sg page frag coalescing in sk_alloc_sg
authorDaniel Borkmann <daniel@iogearbox.net>
Mon, 23 Jul 2018 20:37:54 +0000 (22:37 +0200)
committerDavid S. Miller <davem@davemloft.net>
Tue, 24 Jul 2018 04:28:45 +0000 (21:28 -0700)
Current sg coalescing logic in sk_alloc_sg() (latter is used by tls and
sockmap) is not quite correct in that we do fetch the previous sg entry,
however the subsequent check whether the refilled page frag from the
socket is still the same as from the last entry with prior offset and
length matching the start of the current buffer is comparing always the
first sg list entry instead of the prior one.

Fixes: 3c4d7559159b ("tls: kernel TLS support")
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Acked-by: Dave Watson <davejwatson@fb.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
net/core/sock.c

index 9e8f65585b81152fd9e6c72f7a285a52ef23a686..bc2d7a37297fecfbf3fbddd09ce53931fe0e28af 100644 (file)
@@ -2277,9 +2277,9 @@ int sk_alloc_sg(struct sock *sk, int len, struct scatterlist *sg,
                pfrag->offset += use;
 
                sge = sg + sg_curr - 1;
-               if (sg_curr > first_coalesce && sg_page(sg) == pfrag->page &&
-                   sg->offset + sg->length == orig_offset) {
-                       sg->length += use;
+               if (sg_curr > first_coalesce && sg_page(sge) == pfrag->page &&
+                   sge->offset + sge->length == orig_offset) {
+                       sge->length += use;
                } else {
                        sge = sg + sg_curr;
                        sg_unmark_end(sge);