From patchwork Sat Sep 4 07:40:11 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tetsuo Handa X-Patchwork-Id: 63759 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 88FB2B7155 for ; Sat, 4 Sep 2010 17:40:36 +1000 (EST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753422Ab0IDHkP (ORCPT ); Sat, 4 Sep 2010 03:40:15 -0400 Received: from www262.sakura.ne.jp ([202.181.97.72]:51247 "EHLO www262.sakura.ne.jp" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752574Ab0IDHkP (ORCPT ); Sat, 4 Sep 2010 03:40:15 -0400 Received: from www262.sakura.ne.jp (ksav32.sakura.ne.jp [210.224.165.212]) by www262.sakura.ne.jp (8.14.3/8.14.3) with ESMTP id o847eBQS040776; Sat, 4 Sep 2010 16:40:12 +0900 (JST) (envelope-from penguin-kernel@i-love.sakura.ne.jp) X-Nat-Received: from [202.181.97.72]:53360 [ident-empty] by smtp-proxy.isp with TPROXY id 1283586011.12469 Received: from www262.sakura.ne.jp (localhost [127.0.0.1]) by www262.sakura.ne.jp (8.14.3/8.14.3) with ESMTP id o847eBS7040773; Sat, 4 Sep 2010 16:40:11 +0900 (JST) (envelope-from penguin-kernel@i-love.sakura.ne.jp) Received: (from i-love@localhost) by www262.sakura.ne.jp (8.14.3/8.14.3/Submit) id o847eB4f040772; Sat, 4 Sep 2010 16:40:11 +0900 (JST) (envelope-from penguin-kernel@i-love.sakura.ne.jp) Message-Id: <201009040740.o847eB4f040772@www262.sakura.ne.jp> X-Authentication-Warning: www262.sakura.ne.jp: i-love set sender to penguin-kernel@i-love.sakura.ne.jp using -f Subject: Re: [PATCH] UNIX: Do not loop forever at unix_autobind(). From: Tetsuo Handa To: eric.dumazet@gmail.com Cc: netdev@vger.kernel.org MIME-Version: 1.0 Date: Sat, 04 Sep 2010 16:40:11 +0900 References: <201008212101.IJG87048.QMOHFtSOVOLFFJ@I-love.SAKURA.ne.jp> <201008302227.DJH30258.OQFMFtFJOOVSHL@I-love.SAKURA.ne.jp> <1283370450.2484.19.camel@edumazet-laptop> <201009040658.o846wxnU028775@www262.sakura.ne.jp> <1283584269.3402.9.camel@edumazet-laptop> In-Reply-To: <1283584269.3402.9.camel@edumazet-laptop> X-Anti-Virus: Kaspersky Anti-Virus for Linux Mail Server 5.6.44/RELEASE, bases: 04092010 #4190005, status: clean Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org Eric Dumazet wrote: > Sorry, this wont work very well if you have many processes using > autobind(). Some of them will loop many time before hitting > "stop_ordernum". I see. Then, we should use local counter rather than global counter for yield() checking in case there are multiple threads hitting this loop. ---------------------------------------- From 57a49c7b5a39de58d4538b85c60c758be3d2ce4f Mon Sep 17 00:00:00 2001 From: Tetsuo Handa Date: Sat, 4 Sep 2010 16:23:46 +0900 Subject: [PATCH] UNIX: Do not loop forever at unix_autobind(). We assumed that unix_autobind() never fails if kzalloc() succeeded. But unix_autobind() allows only 1048576 names. If /proc/sys/fs/file-max is larger than 1048576 (e.g. systems with more than 10GB of RAM), a local user can consume all names using fork()/socket()/bind(). If all names are in use, those who call bind() with addr_len == sizeof(short) or connect()/sendmsg() with setsockopt(SO_PASSCRED) will continue while (1) yield(); loop at unix_autobind() till a name becomes available. This patch adds a loop counter in order to give up after 1048576 attempts and use the loop counter in order to count yield() interval more reliably when there are many threads hitting this loop. Note that currently a local user can consume 2GB of kernel memory if the user is allowed to create and autobind 1048576 UNIX domain sockets. We should consider adding some restriction for autobind operation. Signed-off-by: Tetsuo Handa --- net/unix/af_unix.c | 9 ++++++++- 1 files changed, 8 insertions(+), 1 deletions(-) diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c index 4414a18..eedfe50 100644 --- a/net/unix/af_unix.c +++ b/net/unix/af_unix.c @@ -692,6 +692,7 @@ static int unix_autobind(struct socket *sock) static u32 ordernum = 1; struct unix_address *addr; int err; + unsigned int retries = 0; mutex_lock(&u->readlock); @@ -717,8 +718,14 @@ retry: if (__unix_find_socket_byname(net, addr->name, addr->len, sock->type, addr->hash)) { spin_unlock(&unix_table_lock); + /* Give up if all names seems to be in use. */ + if (retries++ == 0xFFFFF) { + err = -ENOMEM; + kfree(addr); + goto out; + } /* Sanity yield. It is unusual case, but yet... */ - if (!(ordernum&0xFF)) + if (!(retries & 0xFF)) yield(); goto retry; }