Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

llc: fix data loss when reading from a socket in llc_ui_recvmsg()

For SOCK_STREAM sockets, if user buffer size (len) is less
than skb size (skb->len), the remaining data from skb
will be lost after calling kfree_skb().

To fix this, move the statement for partial reading
above skb deletion.

Found by InfoTeCS on behalf of Linux Verification Center (linuxtesting.org)

Fixes: 30a584d944fb ("[LLX]: SOCK_DGRAM interface fixes")
Cc: stable@vger.kernel.org
Signed-off-by: Ilia Gavrilov <Ilia.Gavrilov@infotecs.ru>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Ilia Gavrilov and committed by
David S. Miller
239af197 c46286fd

+4 -4
+4 -4
net/llc/af_llc.c
··· 887 887 if (sk->sk_type != SOCK_STREAM) 888 888 goto copy_uaddr; 889 889 890 + /* Partial read */ 891 + if (used + offset < skb_len) 892 + continue; 893 + 890 894 if (!(flags & MSG_PEEK)) { 891 895 skb_unlink(skb, &sk->sk_receive_queue); 892 896 kfree_skb(skb); 893 897 *seq = 0; 894 898 } 895 - 896 - /* Partial read */ 897 - if (used + offset < skb_len) 898 - continue; 899 899 } while (len > 0); 900 900 901 901 out: