summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJames Chapman <jchapman@katalix.com>2008-07-23 23:52:47 -0700
committerGreg Kroah-Hartman <gregkh@suse.de>2008-07-28 10:58:17 -0700
commit0c9b216d1ce5c322631c21bd6656ec35047ffc87 (patch)
tree610befc9cdd058c96242d1472cb79da90f8ea7c4
parentc8330bc571d037b43e116ddfc5ba4a93f334df52 (diff)
l2tp: Fix potential memory corruption in pppol2tp_recvmsg()
[ Upstream commit 6b6707a50c7598a83820077393f8823ab791abf8 ] 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> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-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 a629355ffccf..a3e1d227ce35 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,
err = 0;
skb = skb_recv_datagram(sk, flags & ~MSG_DONTWAIT,
flags & MSG_DONTWAIT, &err);
- if (skb) {
- err = memcpy_toiovec(msg->msg_iov, (unsigned char *) skb->data,
- skb->len);
- if (err < 0)
- goto do_skb_free;
- err = skb->len;
- }
-do_skb_free:
+ if (!skb)
+ goto end;
+
+ if (len > skb->len)
+ len = skb->len;
+ else if (len < skb->len)
+ msg->msg_flags |= MSG_TRUNC;
+
+ err = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, len);
+ if (likely(err == 0))
+ err = len;
+
kfree_skb(skb);
end:
return err;