Received: by 2002:a05:6902:102b:0:0:0:0 with SMTP id x11csp765131ybt; Fri, 19 Jun 2020 13:10:48 -0700 (PDT) X-Google-Smtp-Source: ABdhPJyvO3qq/CDmFa0U+6R9v2PeaurSYjIEHgyhzYqvgJxcFYKZjpImE5O80z3pBlMMxHybWDLR X-Received: by 2002:a05:6402:229b:: with SMTP id cw27mr4975507edb.346.1592597448649; Fri, 19 Jun 2020 13:10:48 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1592597448; cv=none; d=google.com; s=arc-20160816; b=0HOnoecOyN7fR32iG8MoHXxv+MZoOkOsTJhUJLSwNcXCY35odKD417CtJsg/a18Las hSrjDtDWJjArqbUqEmaPfpAZqaqn09kJUtElI2vgdKQYMjzRNYL9nycnK9XhZMQev3V2 4RRB36uAhvmZ6D1r8nb/W++i5rtbK9wYppLbpzeI+aJn58On4tvj2eudcQpnoZhrSFqI hjw4Fx9Ct74S2mUo9OjzmqBDGE0iLWREnaS0Zd9Yy1AfpJf+/F+AdkPoAXdYwGEGY9LE G6IdbS24CmgtU9Vl48AdmIxl4T3rx9tTxxKOqxMkAkE2xShbNVg7IMaVEKdRnRR66gTp HxKw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :user-agent:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=aUETlcQ9x6XO2S8RATWbdFVRPAF0nSiyowQRbAycmr8=; b=ChwungyyNveRdps5U7ifRhKr5ByM14Rm+UpgB6KME/mg+cUSHfSf7la5rEXHnubOb5 jQRrr0AjyS10+mYsoQUTZkxfRo/B6ar+HoHjjMSDJbsueVh1M4lpseH8/fOxfxJ49nPZ ONZPibUvrao7d6tl/myzVW3Y7G9nmA96GUrwrHIUCI7b0/6jOrVExUtQLVob81mThfad cbvn9KDEE4HPND6CJ1m/T+L6Ux/frSRYumik9qGtJt9XQfLs5KBtBPAbUyRQV96e+oym iyD8If8QA34NsK/ek39lMl7CwfsDsr7tkFchbtHNVv3R0uAUbc0vT2vvg1o3pfuv7oFW 5wXQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b="j/LCtPuR"; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id q24si4789762eds.133.2020.06.19.13.10.25; Fri, 19 Jun 2020 13:10:48 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b="j/LCtPuR"; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2390040AbgFSO4J (ORCPT + 99 others); Fri, 19 Jun 2020 10:56:09 -0400 Received: from mail.kernel.org ([198.145.29.99]:50904 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2389659AbgFSOz7 (ORCPT ); Fri, 19 Jun 2020 10:55:59 -0400 Received: from localhost (83-86-89-107.cable.dynamic.v4.ziggo.nl [83.86.89.107]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id 5C4F2217D9; Fri, 19 Jun 2020 14:55:59 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1592578559; bh=2wK3x9Xyezua4jwnu29bAlX1TuakhDFi6UQptDI5vIw=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=j/LCtPuRPlloSqBzSx7DdbzyD6IZWiXV/85xPPPCcfmRWektibyf/bjKzAnvlVxu7 SyFp+ZlRIKJa8S9+6Kf1PVuBDS5dzIznXJKPigR/SN7w65IPZLY7hF/bovZFykrLED 7nEAd7iHC9B9SssLwWe9L+An3vttFCr4ZWQz7XyM= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, syzbot+7d2debdcdb3cb93c1e5e@syzkaller.appspotmail.com, "Eric W. Biederman" Subject: [PATCH 4.19 069/267] proc: Use new_inode not new_inode_pseudo Date: Fri, 19 Jun 2020 16:30:54 +0200 Message-Id: <20200619141652.207568902@linuxfoundation.org> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20200619141648.840376470@linuxfoundation.org> References: <20200619141648.840376470@linuxfoundation.org> User-Agent: quilt/0.66 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Eric W. Biederman commit ef1548adada51a2f32ed7faef50aa465e1b4c5da upstream. Recently syzbot reported that unmounting proc when there is an ongoing inotify watch on the root directory of proc could result in a use after free when the watch is removed after the unmount of proc when the watcher exits. Commit 69879c01a0c3 ("proc: Remove the now unnecessary internal mount of proc") made it easier to unmount proc and allowed syzbot to see the problem, but looking at the code it has been around for a long time. Looking at the code the fsnotify watch should have been removed by fsnotify_sb_delete in generic_shutdown_super. Unfortunately the inode was allocated with new_inode_pseudo instead of new_inode so the inode was not on the sb->s_inodes list. Which prevented fsnotify_unmount_inodes from finding the inode and removing the watch as well as made it so the "VFS: Busy inodes after unmount" warning could not find the inodes to warn about them. Make all of the inodes in proc visible to generic_shutdown_super, and fsnotify_sb_delete by using new_inode instead of new_inode_pseudo. The only functional difference is that new_inode places the inodes on the sb->s_inodes list. I wrote a small test program and I can verify that without changes it can trigger this issue, and by replacing new_inode_pseudo with new_inode the issues goes away. Cc: stable@vger.kernel.org Link: https://lkml.kernel.org/r/000000000000d788c905a7dfa3f4@google.com Reported-by: syzbot+7d2debdcdb3cb93c1e5e@syzkaller.appspotmail.com Fixes: 0097875bd415 ("proc: Implement /proc/thread-self to point at the directory of the current thread") Fixes: 021ada7dff22 ("procfs: switch /proc/self away from proc_dir_entry") Fixes: 51f0885e5415 ("vfs,proc: guarantee unique inodes in /proc") Signed-off-by: "Eric W. Biederman" Signed-off-by: Greg Kroah-Hartman --- fs/proc/inode.c | 2 +- fs/proc/self.c | 2 +- fs/proc/thread_self.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) --- a/fs/proc/inode.c +++ b/fs/proc/inode.c @@ -451,7 +451,7 @@ const struct inode_operations proc_link_ struct inode *proc_get_inode(struct super_block *sb, struct proc_dir_entry *de) { - struct inode *inode = new_inode_pseudo(sb); + struct inode *inode = new_inode(sb); if (inode) { inode->i_ino = de->low_ino; --- a/fs/proc/self.c +++ b/fs/proc/self.c @@ -42,7 +42,7 @@ int proc_setup_self(struct super_block * inode_lock(root_inode); self = d_alloc_name(s->s_root, "self"); if (self) { - struct inode *inode = new_inode_pseudo(s); + struct inode *inode = new_inode(s); if (inode) { inode->i_ino = self_inum; inode->i_mtime = inode->i_atime = inode->i_ctime = current_time(inode); --- a/fs/proc/thread_self.c +++ b/fs/proc/thread_self.c @@ -42,7 +42,7 @@ int proc_setup_thread_self(struct super_ inode_lock(root_inode); thread_self = d_alloc_name(s->s_root, "thread-self"); if (thread_self) { - struct inode *inode = new_inode_pseudo(s); + struct inode *inode = new_inode(s); if (inode) { inode->i_ino = thread_self_inum; inode->i_mtime = inode->i_atime = inode->i_ctime = current_time(inode);