Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753087AbZGJBbY (ORCPT ); Thu, 9 Jul 2009 21:31:24 -0400 Received: (majordomo@vger.kernel.org) by vger.kernel.org id S1752619AbZGJBbA (ORCPT ); Thu, 9 Jul 2009 21:31:00 -0400 Received: from mx2.redhat.com ([66.187.237.31]:35852 "EHLO mx2.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753127AbZGJBa7 (ORCPT ); Thu, 9 Jul 2009 21:30:59 -0400 Date: Fri, 10 Jul 2009 03:27:40 +0200 From: Oleg Nesterov To: James Morris Cc: Christoph Hellwig , David Howells , Roland McGrath , "Serge E. Hallyn" , linux-kernel@vger.kernel.org Subject: [PATCH 2/2] mm_for_maps: take ->cred_guard_mutex to fix the race with exec Message-ID: <20090710012740.GA395@redhat.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline User-Agent: Mutt/1.5.18 (2008-05-17) Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 1693 Lines: 55 The problem is minor, but without ->cred_guard_mutex held we can race with exec() and get the new ->mm but check old creds. Now we do not need to re-check task->mm after ptrace_may_access(), it can't be changed to the new mm under us. Strictly speaking, this also fixes another very minor problem. Unless security check fails or the task exits mm_for_maps() should never return NULL, the caller should get either old or new ->mm. Signed-off-by: Oleg Nesterov --- fs/proc/base.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) --- WAIT/fs/proc/base.c~2_CRED_MUTEX 2009-07-10 02:05:14.000000000 +0200 +++ WAIT/fs/proc/base.c 2009-07-10 03:23:01.000000000 +0200 @@ -234,19 +234,19 @@ static int check_mem_permission(struct t struct mm_struct *mm_for_maps(struct task_struct *task) { - struct mm_struct *mm = get_task_mm(task); + struct mm_struct *mm; - if (mm && mm != current->mm) { - /* - * task->mm can be changed before security check, - * in that case we must notice the change after. - */ - if (!ptrace_may_access(task, PTRACE_MODE_READ) || - mm != task->mm) { - mmput(mm); - mm = NULL; - } + if (mutex_lock_killable(&task->cred_guard_mutex)) + return NULL; + + mm = get_task_mm(task); + if (mm && mm != current->mm && + !ptrace_may_access(task, PTRACE_MODE_READ)) { + mmput(mm); + mm = NULL; } + mutex_unlock(&task->cred_guard_mutex); + return mm; } -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/