From patchwork Tue Mar 15 09:03:44 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexander Potapenko X-Patchwork-Id: 597394 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 3qPTFQ73FZz9s9G for ; Tue, 15 Mar 2016 20:04:10 +1100 (AEDT) Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=google.com header.i=@google.com header.b=A9HR6ndU; dkim-atps=neutral Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S965166AbcCOJEJ (ORCPT ); Tue, 15 Mar 2016 05:04:09 -0400 Received: from mail-wm0-f53.google.com ([74.125.82.53]:36683 "EHLO mail-wm0-f53.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S964798AbcCOJDv (ORCPT ); Tue, 15 Mar 2016 05:03:51 -0400 Received: by mail-wm0-f53.google.com with SMTP id l124so1997140wmf.1 for ; Tue, 15 Mar 2016 02:03:49 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=from:to:cc:subject:date:message-id; bh=qJjNo612R9LHNdZgXkotRnf42d/eyht1cCWVqCk+1ao=; b=A9HR6ndUjSoKR2omCCIZM0o3mSMjM3tnYopi8lFXhsVi+OLFEj64aOzciIDjnpQif5 nsKAKzVs+LKJftI9L8J8/WaDsvK+hnoXP/4C7EO7DZUEfTPjdQtB0UDQiEjZi241o2+i nIwUlahmigI+M0jcoHCEleIzVbV9tVQlHVr/TeX3WbYfinsa1s8zmnJUhQMQvQFo7Ohh WKEfyS0ztraXcfvLBTCsxC9IMNEBZj4NSMtQiBmskvnZPurxrKm0+E79uaAzmRmY38TC dw3qm5OhWmWbiwfM35DDEJyhVgjZKBQEvjMYZQqjap2/Rslm6Hd86M/FFvHkR1O0AXqS mdTw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id; bh=qJjNo612R9LHNdZgXkotRnf42d/eyht1cCWVqCk+1ao=; b=mW3OP4tMJm4i1nMfFv2l2tEZTyhXCPcQaRaN9Cpgda+9FCNj3qp6MrjupCoAwvfdYm e40zePOrf/lBRy8HrcVuz+ELHzj/YHDuWMwDerbNmuwMixaXh58YxQswVeK4iDnB+fRc 66DZn36zzJj0p3WYIFTDIlnRz89usWslDE/xgUCt8xL+dvZEHIvOsl+0IlHrFvwcwDKF CJ89OFHFTar3zAZopPSC5Gd9LOLQVMR3svHFRDQawS0mu0TziL+b3vcxDu7a2hCvCTom 9WQmRzgxu6ZYNnufDOrNTu44qwptTGKFoJ+CFPCw1qcAIaTojsUvsPB2mE/mqCLbz4SC Wf7A== X-Gm-Message-State: AD7BkJKaIpHafIrGyx2AEP3zHR/us4gwKlHmtuFGu78P5U5qOVSn6EGyueNlZ/VC/VA3XzGV X-Received: by 10.28.9.19 with SMTP id 19mr23419355wmj.87.1458032628534; Tue, 15 Mar 2016 02:03:48 -0700 (PDT) Received: from glider0.muc.corp.google.com ([100.105.12.50]) by smtp.gmail.com with ESMTPSA id w133sm19786615wmd.3.2016.03.15.02.03.47 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Tue, 15 Mar 2016 02:03:47 -0700 (PDT) From: Alexander Potapenko To: edumazet@google.com, rweikusat@mobileactivedefense.com, davem@davemloft.net Cc: linux-kernel@vger.kernel.org, netdev@vger.kernel.org Subject: [PATCH] af_unix: closed SOCK_SEQPACKET socketpair must get SIGPIPE Date: Tue, 15 Mar 2016 10:03:44 +0100 Message-Id: <1458032624-139688-1-git-send-email-glider@google.com> X-Mailer: git-send-email 2.7.0.rc3.207.g0ac5344 Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org According to IEEE Std 1003.1, 2013, sending data to a SOCK_SEQPACKET socketpair with MSG_NOSIGNAL flag set must result in a SIGPIPE if the socket is no longer connected. I used the following program to check the kernel behavior: /*****************/ #include #include #include #include #include void PipeHandler(int sig) { fprintf(stderr, "Killed by SIGPIPE\n"); _exit(1); } int main(int argc, char *argv[]) { if (argc < 2) return 0; struct sigaction act; act.sa_handler = PipeHandler; sigaction(SIGPIPE, &act, NULL); int fds[2]; if (strcmp(argv[1], "seqpacket") == 0) { if (socketpair(AF_UNIX, SOCK_SEQPACKET, 0, fds) == -1) return -1; } else { if (strcmp(argv[1], "stream") == 0) { if (socketpair(AF_UNIX, SOCK_STREAM, 0, fds) == -1) return -1; } else { return -1; } } int flags = 0; if ((argc > 2) && (strcmp(argv[2], "nosignal") == 0)) flags = MSG_NOSIGNAL; struct msghdr msg; memset(&msg, 0, sizeof(msg)); close(fds[0]); const ssize_t r = sendmsg(fds[1], &msg, flags); if (r == -1) perror("sendmsg"); return 0; } /*****************/ Without the below patch the behavior is as follows: $ ./sock seqpacket sendmsg: Broken pipe $ ./sock stream Killed by SIGPIPE $ ./sock seqpacket nosignal sendmsg: Broken pipe $ ./sock stream nosignal sendmsg: Broken pipe The behavior of the patched kernel complies with POSIX: $ ./sock seqpacket Killed by SIGPIPE $ ./sock stream Killed by SIGPIPE $ ./sock seqpacket nosignal sendmsg: Broken pipe $ ./sock stream nosignal sendmsg: Broken pipe Signed-off-by: Alexander Potapenko --- net/unix/af_unix.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c index 8fbe6d7..ba34c73 100644 --- a/net/unix/af_unix.c +++ b/net/unix/af_unix.c @@ -1645,6 +1645,7 @@ static int unix_dgram_sendmsg(struct socket *sock, struct msghdr *msg, struct sock *other = NULL; int namelen = 0; /* fake GCC */ int err; + bool send_sigpipe = false; unsigned int hash; struct sk_buff *skb; long timeo; @@ -1675,6 +1676,12 @@ static int unix_dgram_sendmsg(struct socket *sock, struct msghdr *msg, goto out; } + if (sk->sk_shutdown & SEND_SHUTDOWN && sock->type == SOCK_SEQPACKET) { + send_sigpipe = true; + err = -EPIPE; + goto out; + } + if (test_bit(SOCK_PASSCRED, &sock->flags) && !u->addr && (err = unix_autobind(sock)) != 0) goto out; @@ -1769,8 +1776,11 @@ restart_locked: } err = -EPIPE; - if (other->sk_shutdown & RCV_SHUTDOWN) + if (other->sk_shutdown & RCV_SHUTDOWN) { + if (sock->type == SOCK_SEQPACKET) + send_sigpipe = true; goto out_unlock; + } if (sk->sk_type != SOCK_SEQPACKET) { err = security_unix_may_send(sk->sk_socket, other->sk_socket); @@ -1837,6 +1847,8 @@ out: if (other) sock_put(other); scm_destroy(&scm); + if (send_sigpipe && !(msg->msg_flags & MSG_NOSIGNAL)) + send_sig(SIGPIPE, current, 0); return err; }