From patchwork Sat Dec 7 22:26:27 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sasha Levin X-Patchwork-Id: 298718 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 16D7B2C00CE for ; Sun, 8 Dec 2013 09:27:15 +1100 (EST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1758981Ab3LGW04 (ORCPT ); Sat, 7 Dec 2013 17:26:56 -0500 Received: from userp1040.oracle.com ([156.151.31.81]:26705 "EHLO userp1040.oracle.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754289Ab3LGW0y (ORCPT ); Sat, 7 Dec 2013 17:26:54 -0500 Received: from acsinet22.oracle.com (acsinet22.oracle.com [141.146.126.238]) by userp1040.oracle.com (Sentrion-MTA-4.3.1/Sentrion-MTA-4.3.1) with ESMTP id rB7MQZ7u004796 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Sat, 7 Dec 2013 22:26:36 GMT Received: from aserz7022.oracle.com (aserz7022.oracle.com [141.146.126.231]) by acsinet22.oracle.com (8.14.4+Sun/8.14.4) with ESMTP id rB7MQYBM019580 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO); Sat, 7 Dec 2013 22:26:35 GMT Received: from ubhmt103.oracle.com (ubhmt103.oracle.com [156.151.24.8]) by aserz7022.oracle.com (8.14.4+Sun/8.14.4) with ESMTP id rB7MQY1o019574; Sat, 7 Dec 2013 22:26:34 GMT Received: from lappy.hsd1.ma.comcast.net (/10.154.156.176) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Sat, 07 Dec 2013 14:26:34 -0800 From: Sasha Levin To: davem@davemloft.net Cc: edumazet@google.com, netdev@vger.kernel.org, xemul@parallels.com, linux-kernel@vger.kernel.org, Sasha Levin Subject: [PATCH] net: unix: allow set_peek_off to fail Date: Sat, 7 Dec 2013 17:26:27 -0500 Message-Id: <1386455187-28597-1-git-send-email-sasha.levin@oracle.com> X-Mailer: git-send-email 1.8.3.2 X-Source-IP: acsinet22.oracle.com [141.146.126.238] Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org unix_dgram_recvmsg() will hold the readlock of the socket until recv is complete. In the same time, we may try to setsockopt(SO_PEEK_OFF) which will hang until unix_dgram_recvmsg() will complete (which can take a while) without allowing us to break out of it, triggering a hung task spew. Instead, allow set_peek_off to fail, this way userspace will not hang. Signed-off-by: Sasha Levin Acked-by: Pavel Emelyanov --- include/linux/net.h | 2 +- net/core/sock.c | 2 +- net/unix/af_unix.c | 8 ++++++-- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/include/linux/net.h b/include/linux/net.h index 4bcee94..69be3e6 100644 --- a/include/linux/net.h +++ b/include/linux/net.h @@ -181,7 +181,7 @@ struct proto_ops { int offset, size_t size, int flags); ssize_t (*splice_read)(struct socket *sock, loff_t *ppos, struct pipe_inode_info *pipe, size_t len, unsigned int flags); - void (*set_peek_off)(struct sock *sk, int val); + int (*set_peek_off)(struct sock *sk, int val); }; #define DECLARE_SOCKADDR(type, dst, src) \ diff --git a/net/core/sock.c b/net/core/sock.c index ab20ed9..5393b4b 100644 --- a/net/core/sock.c +++ b/net/core/sock.c @@ -882,7 +882,7 @@ set_rcvbuf: case SO_PEEK_OFF: if (sock->ops->set_peek_off) - sock->ops->set_peek_off(sk, val); + ret = sock->ops->set_peek_off(sk, val); else ret = -EOPNOTSUPP; break; diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c index 01625cc..a0ca162 100644 --- a/net/unix/af_unix.c +++ b/net/unix/af_unix.c @@ -530,13 +530,17 @@ static int unix_seqpacket_sendmsg(struct kiocb *, struct socket *, static int unix_seqpacket_recvmsg(struct kiocb *, struct socket *, struct msghdr *, size_t, int); -static void unix_set_peek_off(struct sock *sk, int val) +static int unix_set_peek_off(struct sock *sk, int val) { struct unix_sock *u = unix_sk(sk); - mutex_lock(&u->readlock); + if (mutex_lock_interruptible(&u->readlock)) + return -EINTR; + sk->sk_peek_off = val; mutex_unlock(&u->readlock); + + return 0; }