From patchwork Wed Nov 20 23:55:35 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Junho Ryu X-Patchwork-Id: 292896 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 AA1832C0127 for ; Thu, 21 Nov 2013 11:02:51 +1100 (EST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755279Ab3KUACp (ORCPT ); Wed, 20 Nov 2013 19:02:45 -0500 Received: from mail-pd0-f202.google.com ([209.85.192.202]:34268 "EHLO mail-pd0-f202.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754916Ab3KUACp (ORCPT ); Wed, 20 Nov 2013 19:02:45 -0500 X-Greylist: delayed 422 seconds by postgrey-1.27 at vger.kernel.org; Wed, 20 Nov 2013 19:02:45 EST Received: by mail-pd0-f202.google.com with SMTP id g10so688052pdj.5 for ; Wed, 20 Nov 2013 16:02:44 -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=cDBCW0aLkLOOMJ4EziibZcBBArKqiue+lE5nLjSIcbY=; b=LvfGq6/4VN/q8N36+Is7tTU/5zYCOJY9KhOAQWFseJtdBNNdzgTnr2rKTdvdIHhB1B xblm9+bokO8AVldcZoY6i/+A/+ll22pixuKJcdQ0ZJIYwuVRANl8l4fa03JWk1YcjYPR GLfnnNrdmUx/YPP5Kk6VRtsARd4a/O9s7jbb6QQYEIT4QSdYpinWELke8kwl0AUpROSd 6HjKtmdFo0M4Z7xr5hi3mBEyLrqfVf87HA7v4db4Z2Atwtp7nlOR7zPPrAn/bqmpLggh qL9RU4O6/fzuu4sMxPEPLt1Q9ubhJPmbsYmy40wbiTYQVaZEtd5xL+X0nSCKZhYM1fc4 m2+w== 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=cDBCW0aLkLOOMJ4EziibZcBBArKqiue+lE5nLjSIcbY=; b=cKfR6OTFDNxG2djn43aheOm8Ieqp/EER1gl5T0pG35i9mYi6z8fVoILj47Uz8OxcE+ wXNQmV3gEbMQliTXp+7nMCe4yC2FiaXDN0I7YvbdA5P70OVrS/LVN97NlkP/acatg4CP nnvJynSp0d5aVz9xTB59DaF4Xq6ejOf6kckVy6TAXUJk0vTVbbFwrB31hNfoAJ/Nt9cp oW9vITtYPfWixyLLXY45wf2+ljAbOeuYnIpOPO+BjukKcG+y+ngtUzxs15ZfbMNg2kMi fbGKHUNi+7T96YnMP8ZuwC8dx1QQrwfntqi5qWOqrpIoJ3OxJVptHazoPoN/JoyQd4/x n67Q== X-Gm-Message-State: ALoCoQmTHFyImyRmzkT65qPjTT8nU0zgDQRSwCDxlr0VBKHeaP/RMW3e2quJOnumAUph3U0PRJ4OeLjuSLil899PkGxtpE+Nmw97ShAF5fgNh/pIAoz2Nd0Q1SaKSUf1Ri+ozssntArE2HRje9wF0RXBNr6WyCH+F7CdCKU9Hu4OmHEl/1gQM2gBALRJ41D5l/RuhRuCA0Ry2Yagos9kLnIZ38EA4TuBDw== X-Received: by 10.66.144.133 with SMTP id sm5mr1099210pab.5.1384991742637; Wed, 20 Nov 2013 15:55:42 -0800 (PST) Received: from corp2gmr1-1.hot.corp.google.com (corp2gmr1-1.hot.corp.google.com [172.24.189.92]) by gmr-mx.google.com with ESMTPS id k45si5294959yhn.4.2013.11.20.15.55.42 for (version=TLSv1.1 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Wed, 20 Nov 2013 15:55:42 -0800 (PST) Received: from jayr2.mtv.corp.google.com (jayr2.mtv.corp.google.com [172.17.130.182]) by corp2gmr1-1.hot.corp.google.com (Postfix) with ESMTP id 3B0E831C1DA; Wed, 20 Nov 2013 15:55:42 -0800 (PST) From: Junho Ryu To: linux-ext4@vger.kernel.org Cc: Junho Ryu Subject: [PATCH] ext4: fix use-after-free in ext4_mb_new_blocks Date: Wed, 20 Nov 2013 15:55:35 -0800 Message-Id: <1384991735-18118-1-git-send-email-jayr@google.com> X-Mailer: git-send-email 1.8.4.1 Sender: linux-ext4-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-ext4@vger.kernel.org ext4_mb_put_pa should hold pa->pa_lock before accessing pa->pa_count. While ext4_mb_use_preallocated checks pa->pa_deleted first and then increments pa->count later, ext4_mb_put_pa decrements pa->pa_count before holding pa->pa_lock and then sets pa->pa_deleted. * Free sequence ext4_mb_put_pa (1): atomic_dec_and_test pa->pa_count ext4_mb_put_pa (2): lock pa->pa_lock ext4_mb_put_pa (3): check pa->pa_deleted ext4_mb_put_pa (4): set pa->pa_deleted=1 ext4_mb_put_pa (5): unlock pa->pa_lock ext4_mb_put_pa (6): remove pa from a list ext4_mb_pa_callback: free pa * Use sequence ext4_mb_use_preallocated (1): iterate over preallocation ext4_mb_use_preallocated (2): lock pa->pa_lock ext4_mb_use_preallocated (3): check pa->pa_deleted ext4_mb_use_preallocated (4): increase pa->pa_count ext4_mb_use_preallocated (5): unlock pa->pa_lock ext4_mb_release_context: access pa * Use-after-free sequence [initial status] pa_deleted = 0, pa_count = 1> ext4_mb_use_preallocated (1): iterate over preallocation ext4_mb_use_preallocated (2): lock pa->pa_lock ext4_mb_use_preallocated (3): check pa->pa_deleted ext4_mb_put_pa (1): atomic_dec_and_test pa->pa_count [pa_count decremented] pa_deleted = 0, pa_count = 0> ext4_mb_use_preallocated (4): increase pa->pa_count [pa_count incremented] pa_deleted = 0, pa_count = 1> ext4_mb_use_preallocated (5): unlock pa->pa_lock ext4_mb_put_pa (2): lock pa->pa_lock ext4_mb_put_pa (3): check pa->pa_deleted ext4_mb_put_pa (4): set pa->pa_deleted=1 [race condition!] pa_deleted = 1, pa_count = 1> ext4_mb_put_pa (5): unlock pa->pa_lock ext4_mb_put_pa (6): remove pa from a list ext4_mb_pa_callback: free pa ext4_mb_release_context: access pa AddressSanitizer has detected use-after-free in ext4_mb_new_blocks Bug report: http://goo.gl/rG1On3 Signed-off-by: Junho Ryu --- fs/ext4/mballoc.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c index a41e3ba..83403dd 100644 --- a/fs/ext4/mballoc.c +++ b/fs/ext4/mballoc.c @@ -3442,6 +3442,9 @@ static void ext4_mb_pa_callback(struct rcu_head *head) { struct ext4_prealloc_space *pa; pa = container_of(head, struct ext4_prealloc_space, u.pa_rcu); + + BUG_ON(atomic_read(&pa->pa_count)); + BUG_ON(pa->pa_deleted == 0); kmem_cache_free(ext4_pspace_cachep, pa); } @@ -3455,11 +3458,13 @@ static void ext4_mb_put_pa(struct ext4_allocation_context *ac, ext4_group_t grp; ext4_fsblk_t grp_blk; - if (!atomic_dec_and_test(&pa->pa_count) || pa->pa_free != 0) - return; - /* in this short window concurrent discard can set pa_deleted */ spin_lock(&pa->pa_lock); + if (!atomic_dec_and_test(&pa->pa_count) || pa->pa_free != 0) { + spin_unlock(&pa->pa_lock); + return; + } + if (pa->pa_deleted == 1) { spin_unlock(&pa->pa_lock); return;