From patchwork Wed May 31 03:54:23 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: =?UTF-8?q?=E7=9F=B3=E7=A5=A4?= X-Patchwork-Id: 9755757 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 74264603F7 for ; Wed, 31 May 2017 03:55:32 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 61BAA26785 for ; Wed, 31 May 2017 03:55:32 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 46D7C28485; Wed, 31 May 2017 03:55:32 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.5 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, FREEMAIL_FROM, RCVD_IN_DNSWL_HI, RCVD_IN_SORBS_SPAM autolearn=unavailable version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 9C80126785 for ; Wed, 31 May 2017 03:55:31 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751128AbdEaDzM (ORCPT ); Tue, 30 May 2017 23:55:12 -0400 Received: from mail-io0-f195.google.com ([209.85.223.195]:34787 "EHLO mail-io0-f195.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751119AbdEaDzK (ORCPT ); Tue, 30 May 2017 23:55:10 -0400 Received: by mail-io0-f195.google.com with SMTP id 12so1219141iol.1; Tue, 30 May 2017 20:55:05 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:subject:date:message-id:in-reply-to:references; bh=fGPIV7xkbGhQV7CzuGqU2VXN26ae3B5lhzTLFbhjguM=; b=PZngzYLlbCk+lJtVgrGUu2DD4PDnTUCk5xRMCDLMYaYEqdZsDaL+O9+NU4+tP2WrT6 QRQCfBtxPcqXGAFfKPNOj8I8zUfLLM1uZPFYV8rkcANsdWjkBjloaoFPs9UhGlap4MlM dYXB5cOM7kBpbit1+/Mxs2XLovy5jZQ42nfBAM2O2bm1E/N0Rv3/IfH/ddaYWHvprH5J hBwlqYXpmtZT69QIN0NE9g/1e8XUIsKLtsZncZvyGtRp0/GtYEPsQUD+FUxR5fqwsvo9 oC6f23zea3r1rISpPQEwVfVfDpmLs4F7B8MGthrXDV/CWC+FlR1rDepHuwAoN3opK0rW ElzQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references; bh=fGPIV7xkbGhQV7CzuGqU2VXN26ae3B5lhzTLFbhjguM=; b=nWtZzxnFF6Lra9DFo8uyFgo/hN0inFsEhf8riNI2ROopB/YadMrXE9JEE9fHu0nSYN Z3KL75oAS+aGGOVAW7uCuIPDPWAbZ0ty13p7zd7NAYsl0mYPSNH8lDGGcixzLCeIudVB ZLdp9T/IoRXuYViEtKBRnpjq68gbvBVuSnyWB+5HcsCrBrqeH1uWycj4WTUnwqsUDJo9 EYPjJM/4rh9VWbuZW3MO6og85+WxLNtLL8DhaooJXRNhQft8Z/dBRAyYMMDA0qAgCGu7 BBH0bmJc9BowWLYVtVh42DzEuosYBgQcnC7Av4ZisDx4GZdc7G87HEX4jq3f1eQ5hV+4 +4vA== X-Gm-Message-State: AODbwcD9ccZ1KDF5oH71tF4bHPA/O6/ahc1G4xW5yukLvMk56XSsOhf9 D618K/1dW8MJQQ== X-Received: by 10.157.31.20 with SMTP id x20mr12370570otd.163.1496202894416; Tue, 30 May 2017 20:54:54 -0700 (PDT) Received: from localhost.localdomain ([205.204.117.25]) by smtp.gmail.com with ESMTPSA id p3sm6691122oia.24.2017.05.30.20.54.52 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 30 May 2017 20:54:54 -0700 (PDT) From: "=?UTF-8?q?=E7=9F=B3=E7=A5=A4?=" X-Google-Original-From: =?UTF-8?q?=E7=9F=B3=E7=A5=A4?= To: leilei.lin@alibaba-inc.com, viro@zeniv.linux.org.uk, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, zhiche.yy@alibaba-inc.com Subject: [PATCH 2/2] fsnotify: use method copy_dname copying filename Date: Wed, 31 May 2017 11:54:23 +0800 Message-Id: <20170531035423.70970-3-leilei.lin@alibaba-inc.com> X-Mailer: git-send-email 2.13.0 In-Reply-To: <20170531035423.70970-1-leilei.lin@alibaba-inc.com> References: <20170531035423.70970-1-leilei.lin@alibaba-inc.com> Sender: linux-fsdevel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: "leilei.lin" Kernel got panicked in inotify_handle_event, while running the rename operation against the same file. The root cause is that the race between fsnotify thread and file rename thread. When fsnotify thread was copying the dentry name, another rename thread could change the dentry name at same time. With slub_debug=FZ boot args, this bug will trigger a trace like the following: [ 87.733653] ============================================================================= [ 87.735350] BUG kmalloc-64 (Not tainted): Redzone overwritten [ 87.736550] ----------------------------------------------------------------------------- [ 87.738466] Disabling lock debugging due to kernel taint [ 87.739556] INFO: 0xffff8e487a50b0f8-0xffff8e487a50b0fc. First byte 0x33 instead of 0xcc [ 87.741188] INFO: Slab 0xfffff116c0e942c0 objects=46 used=43 fp=0xffff8e487a50bf80 flags=0xffff8000000101 [ 87.743133] INFO: Object 0xffff8e487a50b0b8 @offset=184 fp=0xffff8e487a50b0b8 [ 87.744942] Redzone ffff8e487a50b0b0: cc cc cc cc cc cc cc cc ........ [ 87.746743] Object ffff8e487a50b0b8: b8 b0 50 7a 48 8e ff ff b8 b0 50 7a 48 8e ff ff ..PzH.....PzH... [ 87.748621] Object ffff8e487a50b0c8: 60 75 7e 7b 48 8e ff ff 08 00 00 08 00 00 00 00 `u~{H........... [ 87.750583] Object ffff8e487a50b0d8: 01 00 00 00 00 00 00 00 0d 00 00 00 74 64 63 5f ............tdc_ [ 87.752541] Object ffff8e487a50b0e8: 61 64 6d 69 6e 2e 4c 4f 47 2e 31 31 32 33 31 32 admin.LOG.112312 [ 87.754431] Redzone ffff8e487a50b0f8: 33 31 32 33 00 cc cc cc 3123.... [ 87.756172] Padding ffff8e487a50b100: 00 00 00 00 00 00 00 00 ........ [ 87.757988] CPU: 0 PID: 286 Comm: python Tainted: G B 4.11.0-rc4+ #29 [ 87.759574] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.9.1-0-gb3ef39f-prebuilt.qemu-project.org 04/01/2014 [ 87.761878] Call Trace: [ 87.762381] dump_stack+0x65/0x88 [ 87.763063] print_trailer+0x15d/0x250 [ 87.763833] check_bytes_and_report+0xcd/0x110 [ 87.764731] check_object+0x1ce/0x290 [ 87.765472] free_debug_processing+0x9c/0x2e3 [ 87.766362] ? inotify_free_event+0xe/0x10 [ 87.767191] __slab_free+0x1ba/0x2b0 [ 87.767922] ? async_page_fault+0x28/0x30 [ 87.768731] ? inotify_free_event+0xe/0x10 [ 87.769558] kfree+0x165/0x1a0 [ 87.770184] inotify_free_event+0xe/0x10 [ 87.770974] fsnotify_destroy_event+0x51/0x70 [ 87.771851] inotify_read+0x1dc/0x3a0 [ 87.772582] ? do_wait_intr_irq+0xa0/0xa0 [ 87.773388] __vfs_read+0x37/0x150 [ 87.774078] ? security_file_permission+0x9d/0xc0 [ 87.775009] vfs_read+0x8c/0x130 [ 87.775657] SyS_read+0x55/0xc0 [ 87.776328] entry_SYSCALL_64_fastpath+0x1e/0xad [ 87.777280] RIP: 0033:0x7fcc1375b210 [ 87.778001] RSP: 002b:00007ffe2f00b838 EFLAGS: 00000246 ORIG_RAX: 0000000000000000 [ 87.779513] RAX: ffffffffffffffda RBX: 00007fcc1303d7b8 RCX: 00007fcc1375b210 [ 87.780932] RDX: 0000000000005c70 RSI: 00000000013fe9f4 RDI: 0000000000000004 [ 87.782337] RBP: 00007fcc1303d760 R08: 0000000000000080 R09: 0000000000005c95 [ 87.783780] R10: 0000000000000073 R11: 0000000000000246 R12: 0000000000005c95 [ 87.785203] R13: 0000000000002708 R14: 0000000000005ca1 R15: 00007fcc1303d7b8 [ 87.786636] FIX kmalloc-64: Restoring 0xffff8e487a50b0f8-0xffff8e487a50b0fc=0xcc [ 87.789388] FIX kmalloc-64: Object at 0xffff8e487a50b0b8 not freed Graph below is the flow of inotify subsystem handling notify event. If a rename syscall happened simultaneously, for example filename of "foobar" is rename to "foobar_longername", which would access memory illegally. CPU 1 CPU 2 fsnotify() inotify_handle_event() strlen(file_name) // file_name -> "foobar" rename happen file_name -> "foobar_longername" alloc_len += len + 1; event = kmalloc(alloc_len, GFP_KERNEL); strcpy(event->name, file_name); -> overwritten Signed-off-by: leilei.lin --- fs/notify/fsnotify.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/fs/notify/fsnotify.c b/fs/notify/fsnotify.c index b41515d..2c6f94d 100644 --- a/fs/notify/fsnotify.c +++ b/fs/notify/fsnotify.c @@ -91,6 +91,7 @@ int __fsnotify_parent(const struct path *path, struct dentry *dentry, __u32 mask struct dentry *parent; struct inode *p_inode; int ret = 0; + char *name = NULL; if (!dentry) dentry = path->dentry; @@ -108,14 +109,23 @@ int __fsnotify_parent(const struct path *path, struct dentry *dentry, __u32 mask * specifies these are events which came from a child. */ mask |= FS_EVENT_ON_CHILD; + ret = copy_dname(dentry, &name); + + if (ret) { + dput(parent); + return ret; + } + if (path) ret = fsnotify(p_inode, mask, path, FSNOTIFY_EVENT_PATH, - dentry->d_name.name, 0); + name, 0); else ret = fsnotify(p_inode, mask, dentry->d_inode, FSNOTIFY_EVENT_INODE, - dentry->d_name.name, 0); + name, 0); } + kfree(name); + dput(parent); return ret;