Received: by 2002:ad5:474a:0:0:0:0:0 with SMTP id i10csp750603imu; Fri, 16 Nov 2018 09:35:07 -0800 (PST) X-Google-Smtp-Source: AJdET5fbtnOSUcdVzF41wBDuyD9qobo3O+D3WCCNV68Mv+PrB/SzT4z83z+P6T+utbU+t2CH2BuK X-Received: by 2002:a17:902:5ac7:: with SMTP id g7mr11957803plm.212.1542389707413; Fri, 16 Nov 2018 09:35:07 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1542389707; cv=none; d=google.com; s=arc-20160816; b=s+vu6ljwB8L+LzuDGSExbLMXnpkYCfXdnKMoGBBNGdpJXmbM6BgIp4yl0m0wWUAeYi +Vf3bwl69VLTNvXsSRfQhnxw6zdfwB0HTUB0sgU7k8qi9AY2lX8lw3RjngaVan8zBJHT eoqW4YvdIb4G9UDZArThSnUROVMHNk+aoAEg6T+lKAq6cEEkWRBgZAGyZSEyTH4uNW2a 0eCpVQk/S7D+oWVixNHMcmGBFxgylp8jSJmdGDN7JJ/+68oa2UieUHKykvC58kI3JFqE fhC5aGxFJwOCX747TKqIhtWKyuaNmTQuIkItoHld/MtbPN507/UpkZkLDDXhARa05R8g la6A== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:references :in-reply-to:message-id:date:subject:cc:to:from; bh=a+QOUhUbztNue2BSNWFau40ZeXXFhn99PcnhPRVTxqA=; b=R3tuZ2TWp4ND0TTCL68cf6Lwihi9SDmGkv8fCbEhGDOf80VQJs6Ec5VmW8KcEoQ6YM dDbjca0BG6Eg1V63PAYCtcgCtRUbWw5Nk2exSMgIMeXpZ1q56ZG/JB0MbRaT8KDtFhku SxEuKsgzzi+OLitJgnokmzeD29SGHJgJnPne0+fDvgPjU5FZs7JI2u69tLsUchoU6kDU t6C+/6UhEvHfVTesJBBajswKXdguu1IDcsPyKlwdUMAdrT6LUP8SryhKw4yp4tVtV337 t42SC6V1BCD76H5YBdvH52w/K0ZBh8y9z60acoepxZmeOhH9b51IkslIBOtxLNe5h9dq zBBw== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=redhat.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id g19-v6si241674plq.69.2018.11.16.09.34.53; Fri, 16 Nov 2018 09:35:07 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=redhat.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2390137AbeKQDra (ORCPT + 99 others); Fri, 16 Nov 2018 22:47:30 -0500 Received: from mx1.redhat.com ([209.132.183.28]:35190 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729140AbeKQDr3 (ORCPT ); Fri, 16 Nov 2018 22:47:29 -0500 Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 2F6BA3082B22; Fri, 16 Nov 2018 17:34:12 +0000 (UTC) Received: from madcap2.tricolour.ca (ovpn-112-24.phx2.redhat.com [10.3.112.24]) by smtp.corp.redhat.com (Postfix) with ESMTP id CDD3F60E1C; Fri, 16 Nov 2018 17:34:09 +0000 (UTC) From: Richard Guy Briggs To: linux-fsdevel@vger.kernel.org, viro@ZenIV.linux.org.uk, LKML , Linux-Audit Mailing List Cc: Paul Moore , Eric Paris , Steve Grubb , Richard Guy Briggs Subject: [RFC PATCH ghak100 V1 1/2] audit: avoid fcaps on MNT_FORCE Date: Fri, 16 Nov 2018 12:33:13 -0500 Message-Id: <218e806e61cd5ae2fd38f9d546f953f86c763b58.1542149969.git.rgb@redhat.com> In-Reply-To: References: In-Reply-To: References: X-Scanned-By: MIMEDefang 2.79 on 10.5.11.12 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.45]); Fri, 16 Nov 2018 17:34:12 +0000 (UTC) Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Don't fetch fcaps when umount2 is called with MNT_FORCE to avoid a process hang while it waits for the missing resource to (possibly never) re-appear. Note the comment above user_path_mountpoint_at(): * A umount is a special case for path walking. We're not actually interested * in the inode in this situation, and ESTALE errors can be a problem. We * simply want track down the dentry and vfsmount attached at the mountpoint * and avoid revalidating the last component. This can happen on ceph, cifs, 9p, lustre, fuse (gluster) or NFS. Please see the github issue tracker https://github.com/linux-audit/audit-kernel/issues/100 Signed-off-by: Richard Guy Briggs --- fs/namei.c | 2 +- fs/namespace.c | 3 +++ include/linux/audit.h | 8 ++++++-- kernel/audit.c | 5 +++-- kernel/audit.h | 2 +- kernel/auditsc.c | 6 +++--- 6 files changed, 17 insertions(+), 9 deletions(-) diff --git a/fs/namei.c b/fs/namei.c index 0cab6494978c..5ac8410b704c 100644 --- a/fs/namei.c +++ b/fs/namei.c @@ -2720,7 +2720,7 @@ int user_path_at_empty(int dfd, const char __user *name, unsigned flags, if (unlikely(error == -ESTALE)) error = path_mountpoint(&nd, flags | LOOKUP_REVAL, path); if (likely(!error)) - audit_inode(name, path->dentry, 0); + audit_inode(name, path->dentry, flags & LOOKUP_NO_REVAL); restore_nameidata(); putname(name); return error; diff --git a/fs/namespace.c b/fs/namespace.c index 99186556f8d3..5bae5bbd4e1f 100644 --- a/fs/namespace.c +++ b/fs/namespace.c @@ -1636,6 +1636,9 @@ int ksys_umount(char __user *name, int flags) if (!(flags & UMOUNT_NOFOLLOW)) lookup_flags |= LOOKUP_FOLLOW; + if (!(flags & MNT_FORCE)) + lookup_flags |= LOOKUP_NO_REVAL; + retval = user_path_mountpoint_at(AT_FDCWD, name, lookup_flags, &path); if (retval) goto out; diff --git a/include/linux/audit.h b/include/linux/audit.h index 9334fbef7bae..503f1710c9d0 100644 --- a/include/linux/audit.h +++ b/include/linux/audit.h @@ -25,6 +25,7 @@ #include #include +#include /* LOOKUP_* */ #include #define AUDIT_INO_UNSET ((unsigned long)-1) @@ -229,6 +230,7 @@ extern void __audit_syscall_entry(int major, unsigned long a0, unsigned long a1, #define AUDIT_INODE_PARENT 1 /* dentry represents the parent */ #define AUDIT_INODE_HIDDEN 2 /* audit record should be hidden */ +#define AUDIT_INODE_NOREVAL 4 /* audit record incomplete */ extern void __audit_inode(struct filename *name, const struct dentry *dentry, unsigned int flags); extern void __audit_file(const struct file *); @@ -289,11 +291,13 @@ static inline void audit_getname(struct filename *name) } static inline void audit_inode(struct filename *name, const struct dentry *dentry, - unsigned int parent) { + unsigned int lflags) { if (unlikely(!audit_dummy_context())) { unsigned int flags = 0; - if (parent) + if (lflags & LOOKUP_PARENT) flags |= AUDIT_INODE_PARENT; + if (lflags & LOOKUP_NO_REVAL) + flags |= AUDIT_INODE_NOREVAL; __audit_inode(name, dentry, flags); } } diff --git a/kernel/audit.c b/kernel/audit.c index 2a8058764aa6..45ca6d15ce89 100644 --- a/kernel/audit.c +++ b/kernel/audit.c @@ -2097,7 +2097,7 @@ static inline int audit_copy_fcaps(struct audit_names *name, /* Copy inode data into an audit_names. */ void audit_copy_inode(struct audit_names *name, const struct dentry *dentry, - struct inode *inode) + struct inode *inode, unsigned int flags) { name->ino = inode->i_ino; name->dev = inode->i_sb->s_dev; @@ -2106,7 +2106,8 @@ void audit_copy_inode(struct audit_names *name, const struct dentry *dentry, name->gid = inode->i_gid; name->rdev = inode->i_rdev; security_inode_getsecid(inode, &name->osid); - audit_copy_fcaps(name, dentry); + if (!(flags & AUDIT_INODE_NOREVAL)) + audit_copy_fcaps(name, dentry); } /** diff --git a/kernel/audit.h b/kernel/audit.h index 214e14948370..7db09151c2d0 100644 --- a/kernel/audit.h +++ b/kernel/audit.h @@ -212,7 +212,7 @@ struct audit_context { extern void audit_copy_inode(struct audit_names *name, const struct dentry *dentry, - struct inode *inode); + struct inode *inode, unsigned int flags); extern void audit_log_cap(struct audit_buffer *ab, char *prefix, kernel_cap_t *cap); extern void audit_log_name(struct audit_context *context, diff --git a/kernel/auditsc.c b/kernel/auditsc.c index b2d1f043f17f..d39a7fbaf944 100644 --- a/kernel/auditsc.c +++ b/kernel/auditsc.c @@ -1846,7 +1846,7 @@ void __audit_inode(struct filename *name, const struct dentry *dentry, n->type = AUDIT_TYPE_NORMAL; } handle_path(dentry); - audit_copy_inode(n, dentry, inode); + audit_copy_inode(n, dentry, inode, flags & AUDIT_INODE_NOREVAL); } void __audit_file(const struct file *file) @@ -1947,7 +1947,7 @@ void __audit_inode_child(struct inode *parent, n = audit_alloc_name(context, AUDIT_TYPE_PARENT); if (!n) return; - audit_copy_inode(n, NULL, parent); + audit_copy_inode(n, NULL, parent, 0); } if (!found_child) { @@ -1966,7 +1966,7 @@ void __audit_inode_child(struct inode *parent, } if (inode) - audit_copy_inode(found_child, dentry, inode); + audit_copy_inode(found_child, dentry, inode, 0); else found_child->ino = AUDIT_INO_UNSET; } -- 1.8.3.1