Sophie

Sophie

distrib > Scientific%20Linux > 5x > x86_64 > by-pkgid > fc11cd6e1c513a17304da94a5390f3cd > files > 3066

kernel-2.6.18-194.11.1.el5.src.rpm

From: Hans-Joachim Picht <hpicht@redhat.com>
Date: Fri, 27 Feb 2009 20:51:14 +0100
Subject: [s390] af_iucv: hang if recvmsg is used with MSG_PEEK
Message-id: 20090227195114.GO2447@redhat.com
O-Subject: [RHEL5 U4 PATCH 1/7] s390 - af_iucv: System hang if recvmsg() is used with MSG_PEEK
Bugzilla: 487703

Description
============

Receiving socket data with MSG_PEEK flag set causes a systen hang.

If iucv_sock_recvmsg() is called with the MSG_PEEK flag set,
the skb is enqueued twice. If the socket is then closed, the
pointer to the skb is also freed twice and causes a kernel oops.

Solution: Remove the skb_queue_head() call for MSG_PEEK, because the
skb_recv_datagram() function already handles MSG_PEEK (it
actually does not dequeue the skb).

Bugzilla
=========

BZ 487703
https://bugzilla.redhat.com/show_bug.cgi?id=487703

Upstream status of the patch:
=============================

This patch is included in linux-2.6 as
git commit e2e5a0f2b100a5204d27def8bbf73333d1710be2

Test status:
============

The patch has been tested and fixes the problem.
The fix has been verified by the IBM test department.

Please ACK.

With best regards,

	--Hans

diff --git a/net/iucv/af_iucv.c b/net/iucv/af_iucv.c
index feac18b..8038be3 100644
--- a/net/iucv/af_iucv.c
+++ b/net/iucv/af_iucv.c
@@ -780,6 +780,8 @@ static int iucv_sock_recvmsg(struct kiocb *iocb, struct socket *sock,
 
 	target = sock_rcvlowat(sk, flags & MSG_WAITALL, len);
 
+	/* receive/dequeue next skb:
+	 * the function understands MSG_PEEK and, thus, does not dequeue skb */
 	skb = skb_recv_datagram(sk, flags, noblock, &err);
 	if (!skb) {
 		if (sk->sk_shutdown & RCV_SHUTDOWN)
@@ -827,9 +829,7 @@ static int iucv_sock_recvmsg(struct kiocb *iocb, struct socket *sock,
 				iucv_process_message_q(sk);
 			spin_unlock_bh(&iucv->message_q.lock);
 		}
-
-	} else
-		skb_queue_head(&sk->sk_receive_queue, skb);
+	}
 
 done:
 	return err ? : copied;