From patchwork Wed Mar 9 14:10:23 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexander Potapenko X-Patchwork-Id: 595078 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 5957114031D for ; Thu, 10 Mar 2016 01:10:57 +1100 (AEDT) Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=google.com header.i=@google.com header.b=OqnNkFXk; dkim-atps=neutral Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932654AbcCIOKb (ORCPT ); Wed, 9 Mar 2016 09:10:31 -0500 Received: from mail-wm0-f52.google.com ([74.125.82.52]:34316 "EHLO mail-wm0-f52.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1750803AbcCIOK3 (ORCPT ); Wed, 9 Mar 2016 09:10:29 -0500 Received: by mail-wm0-f52.google.com with SMTP id p65so194003664wmp.1 for ; Wed, 09 Mar 2016 06:10:28 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=from:to:cc:subject:date:message-id; bh=qy8PRGHcGkIIgl258vRxJT3f4bjY5BSfX44FVpNxFo4=; b=OqnNkFXkBaq1hx8XgNAFZkBLeNgsWQN1zCwFafMKRt0m6vuhBDXGip7SLDm9gLdRJk PzZdkrWpV74so9rzxVzkW+DmDZGOQd9xXPeG3+S1QqIQybPnVNBw4ae1bfI8Fr+VpQ8R SC9j2On0B+vRxeFfmdv3g0TJQLaj+hJqkhXtnQLySpqCL4ZQS67/ubBlyb8m/do5UddB URFZcEw8RwGknmvYtjgF55JZS5VNCfC5Whzp0YHk6aVtxxrI6gYs05RbsYmvT3mxtwI3 aCGi/r3nQ9Fyak0+68HsgoKwry7fUlYHPdUkCb4u32hRJKUjRNlKu3y0DnV3pSl+vkDj aZEg== 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=qy8PRGHcGkIIgl258vRxJT3f4bjY5BSfX44FVpNxFo4=; b=dd6wuDedWc4Kz7KJa8s2IF7VSN1L2t38TSxmxoQ+jDWyOEcCPsI3d+gbZVy2XDTBG/ /nP49xf8tsXGHLHeEpmdDLGG/q3yZlp2n929ESK0uE6FhHoJxL0JoYnp0Y4XTDCPoIk/ Em7QHXaUb/Mhq44pqP6dTkBSPAZSnfHtqS50XdFv3Olc8Qsvx6p74vETAIjzSp/KPV9E uQOx8jYa2aThNDqz8FPzxO/KHQdT0N1gfURZOmaETrK1mhFM5pCNxKLv/128geWGXzrA YecR84Cg0T7xVQQIJJDE0LMPshStbhXUY5j3oMKtgzkG6IG9bsqX1HTJwZsUFCeF4/Ku wuAg== X-Gm-Message-State: AD7BkJKbJc43qWhRfL6q4GVVixeLEanzXD+xiIjpUaGt/GAe2YCQMC5ezZa/TGKgrl4G5nr5 X-Received: by 10.28.175.139 with SMTP id y133mr24422049wme.45.1457532627832; Wed, 09 Mar 2016 06:10:27 -0800 (PST) Received: from glider0.muc.corp.google.com ([100.105.12.50]) by smtp.gmail.com with ESMTPSA id bg1sm8154393wjc.27.2016.03.09.06.10.26 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Wed, 09 Mar 2016 06:10:26 -0800 (PST) From: Alexander Potapenko To: edumazet@google.com, rweikusat@mobileactivedefense.com Cc: linux-kernel@vger.kernel.org, netdev@vger.kernel.org Subject: [PATCH] SOCK_SEQPACKET socketpair must get SIGPIPE in AF_UNIX if one end is closed Date: Wed, 9 Mar 2016 15:10:23 +0100 Message-Id: <1457532623-125301-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. Signed-off-by: Alexander Potapenko --- 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 --- 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; }