aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJames Chapman <jchapman@katalix.com>2008-06-10 15:35:00 -0400
committerDavid S. Miller <davem@davemloft.net>2008-06-10 15:35:00 -0400
commit6b6707a50c7598a83820077393f8823ab791abf8 (patch)
tree5a707de3b34eeaa2bad9b16d5ad006abe4a6d901
parent2e761e0532a784816e7e822dbaaece8c5d4be14d (diff)
l2tp: Fix potential memory corruption in pppol2tp_recvmsg()
This patch fixes a potential memory corruption in pppol2tp_recvmsg(). If skb->len is bigger than the caller's buffer length, memcpy_toiovec() will go into unintialized data on the kernel heap, interpret it as an iovec and start modifying memory. The fix is to change the memcpy_toiovec() call to skb_copy_datagram_iovec() so that paged packets (rare for PPPOL2TP) are handled properly. Also check that the caller's buffer is big enough for the data and set the MSG_TRUNC flag if it is not so. Reported-by: Ilja <ilja@netric.org> Signed-off-by: James Chapman <jchapman@katalix.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/pppol2tp.c20
1 files changed, 12 insertions, 8 deletions
diff --git a/drivers/net/pppol2tp.c b/drivers/net/pppol2tp.c
index 70cfdb46aa27..f9298827a76c 100644
--- a/drivers/net/pppol2tp.c
+++ b/drivers/net/pppol2tp.c
@@ -783,14 +783,18 @@ static int pppol2tp_recvmsg(struct kiocb *iocb, struct socket *sock,
783 err = 0; 783 err = 0;
784 skb = skb_recv_datagram(sk, flags & ~MSG_DONTWAIT, 784 skb = skb_recv_datagram(sk, flags & ~MSG_DONTWAIT,
785 flags & MSG_DONTWAIT, &err); 785 flags & MSG_DONTWAIT, &err);
786 if (skb) { 786 if (!skb)
787 err = memcpy_toiovec(msg->msg_iov, (unsigned char *) skb->data, 787 goto end;
788 skb->len); 788
789 if (err < 0) 789 if (len > skb->len)
790 goto do_skb_free; 790 len = skb->len;
791 err = skb->len; 791 else if (len < skb->len)
792 } 792 msg->msg_flags |= MSG_TRUNC;
793do_skb_free: 793
794 err = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, len);
795 if (likely(err == 0))
796 err = len;
797
794 kfree_skb(skb); 798 kfree_skb(skb);
795end: 799end:
796 return err; 800 return err;