From patchwork Mon Dec 2 09:36:59 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yann Droneaud X-Patchwork-Id: 295846 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 280DC2C0040 for ; Mon, 2 Dec 2013 20:37:51 +1100 (EST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753288Ab3LBJhh (ORCPT ); Mon, 2 Dec 2013 04:37:37 -0500 Received: from smtp3-g21.free.fr ([212.27.42.3]:50296 "EHLO smtp3-g21.free.fr" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752562Ab3LBJhf (ORCPT ); Mon, 2 Dec 2013 04:37:35 -0500 Received: from localhost.localdomain (unknown [37.163.28.200]) by smtp3-g21.free.fr (Postfix) with ESMTP id 32149A634F; Mon, 2 Dec 2013 10:37:21 +0100 (CET) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by localhost.localdomain (8.14.7/8.14.7) with ESMTP id rB29bCO7012412; Mon, 2 Dec 2013 10:37:13 +0100 Received: (from ydroneaud@localhost) by localhost.localdomain (8.14.7/8.14.7/Submit) id rB29b6Sd012411; Mon, 2 Dec 2013 10:37:06 +0100 From: Yann Droneaud To: netdev@vger.kernel.org, linux-kernel@vger.kernel.org Cc: Yann Droneaud , "David S. Miller" , Al Viro Subject: [PATCH] net: use a proper error path in socketpair() Date: Mon, 2 Dec 2013 10:36:59 +0100 Message-Id: <1385977019-12282-1-git-send-email-ydroneaud@opteya.com> X-Mailer: git-send-email 1.8.4.2 Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org socketpair() use overly complicated and redundant error paths. This patch makes socketpair() use a single error path, which do not rely on heavy-weight call to sys_close(): it's better to try to push the file descriptor to userspace before installing the socket file to the file descriptor, so that errors are catched earlier and being easier to handle. Cc: David S. Miller Cc: Al Viro Signed-off-by: Yann Droneaud --- net/socket.c | 41 ++++++++++++++++++++++------------------- 1 file changed, 22 insertions(+), 19 deletions(-) diff --git a/net/socket.c b/net/socket.c index 0b18693f2be6..bcc1cbd2087f 100644 --- a/net/socket.c +++ b/net/socket.c @@ -1445,48 +1445,51 @@ SYSCALL_DEFINE4(socketpair, int, family, int, type, int, protocol, err = fd1; goto out_release_both; } + fd2 = get_unused_fd_flags(flags); if (unlikely(fd2 < 0)) { err = fd2; - put_unused_fd(fd1); - goto out_release_both; + goto out_put_unused_1; } newfile1 = sock_alloc_file(sock1, flags, NULL); if (unlikely(IS_ERR(newfile1))) { err = PTR_ERR(newfile1); - put_unused_fd(fd1); - put_unused_fd(fd2); - goto out_release_both; + goto out_put_unused_both; } newfile2 = sock_alloc_file(sock2, flags, NULL); if (IS_ERR(newfile2)) { err = PTR_ERR(newfile2); - fput(newfile1); - put_unused_fd(fd1); - put_unused_fd(fd2); - sock_release(sock2); - goto out; + goto out_fput_1; } + err = put_user(fd1, &usockvec[0]); + if (err) + goto out_fput_both; + + err = put_user(fd2, &usockvec[1]); + if (err) + goto out_fput_both; + audit_fd_pair(fd1, fd2); + fd_install(fd1, newfile1); fd_install(fd2, newfile2); /* fd1 and fd2 may be already another descriptors. * Not kernel problem. */ - err = put_user(fd1, &usockvec[0]); - if (!err) - err = put_user(fd2, &usockvec[1]); - if (!err) - return 0; - - sys_close(fd2); - sys_close(fd1); - return err; + return 0; +out_fput_both: + fput(newfile2); +out_fput_1: + fput(newfile1); +out_put_unused_both: + put_unused_fd(fd2); +out_put_unused_1: + put_unused_fd(fd1); out_release_both: sock_release(sock2); out_release_1: