From patchwork Thu Mar 28 17:50:40 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 10875603 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id A72251708 for ; Thu, 28 Mar 2019 17:50:49 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 9388528E8E for ; Thu, 28 Mar 2019 17:50:49 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 9184128EDA; Thu, 28 Mar 2019 17:50:49 +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=-5.5 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI, SUSPICIOUS_RECIPS,UNPARSEABLE_RELAY 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 2FDA028F23 for ; Thu, 28 Mar 2019 17:50:49 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727606AbfC1Rur (ORCPT ); Thu, 28 Mar 2019 13:50:47 -0400 Received: from aserp2130.oracle.com ([141.146.126.79]:40288 "EHLO aserp2130.oracle.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726453AbfC1Rur (ORCPT ); Thu, 28 Mar 2019 13:50:47 -0400 Received: from pps.filterd (aserp2130.oracle.com [127.0.0.1]) by aserp2130.oracle.com (8.16.0.27/8.16.0.27) with SMTP id x2SHnInj049215; Thu, 28 Mar 2019 17:50:44 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oracle.com; h=subject : from : to : cc : date : message-id : in-reply-to : references : mime-version : content-type : content-transfer-encoding; s=corp-2018-07-02; bh=9mq463y6Fy+tnAy6EAF3waabQKAMjMyUGNNPLiFAWs8=; b=06/ipe6rPVPCmRT+ZDZ1UYm6lTddupzdsLbZKnyxxACsXOMVgVpbAqwVHWoOXiMGJm5K TBtsCl8fw8vRWdtMYTIo5Ooi8xDSsY6rl2/11GAH3q58pYxhznYZN1Vzz53wxcUBWCsL 0Q6+TB/he1b1fT2DL6djhk+Vj9AMCZn0fOqrtUCSt/NPENvnctzuHqpvfDrZRPddQs5o xP0dQlC2+i9gGmAoaOIwLHDB/XBtppbrHEjAu392Q7PuTER+K/ULqEmy3Bu6yak6Flnc 9SaA/mRSn3v2ZIb484gddpklZUrBJDrbh1w6dHOugyZ6V9TlDIBf7LFnW8GoZk9OolD0 oQ== Received: from userv0021.oracle.com (userv0021.oracle.com [156.151.31.71]) by aserp2130.oracle.com with ESMTP id 2re6g187wm-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Thu, 28 Mar 2019 17:50:43 +0000 Received: from userv0121.oracle.com (userv0121.oracle.com [156.151.31.72]) by userv0021.oracle.com (8.14.4/8.14.4) with ESMTP id x2SHogvP030296 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Thu, 28 Mar 2019 17:50:43 GMT Received: from abhmp0020.oracle.com (abhmp0020.oracle.com [141.146.116.26]) by userv0121.oracle.com (8.14.4/8.13.8) with ESMTP id x2SHogTt009429; Thu, 28 Mar 2019 17:50:42 GMT Received: from localhost (/10.159.234.216) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Thu, 28 Mar 2019 10:50:42 -0700 Subject: [PATCH 1/3] mm/fs: don't allow writes to immutable files From: "Darrick J. Wong" To: darrick.wong@oracle.com Cc: linux-xfs@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-ext4@vger.kernel.org, linux-btrfs@vger.kernel.org, linux-mm@kvack.org Date: Thu, 28 Mar 2019 10:50:40 -0700 Message-ID: <155379544071.24796.11489520877297987568.stgit@magnolia> In-Reply-To: <155379543409.24796.5783716624820175068.stgit@magnolia> References: <155379543409.24796.5783716624820175068.stgit@magnolia> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 X-Proofpoint-Virus-Version: vendor=nai engine=5900 definitions=9209 signatures=668685 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 priorityscore=1501 malwarescore=0 suspectscore=1 phishscore=0 bulkscore=0 spamscore=0 clxscore=1015 lowpriorityscore=0 mlxscore=0 impostorscore=0 mlxlogscore=240 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1810050000 definitions=main-1903280117 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: Darrick J. Wong The chattr manpage has this to say about immutable files: "A file with the 'i' attribute cannot be modified: it cannot be deleted or renamed, no link can be created to this file, most of the file's metadata can not be modified, and the file can not be opened in write mode." Once the flag is set, it is enforced for quite a few file operations, such as fallocate, fpunch, fzero, rm, touch, open, etc. However, we don't check for immutability when doing a write(), a PROT_WRITE mmap(), a truncate(), or a write to a previously established mmap. If a program has an open write fd to a file that the administrator subsequently marks immutable, the program still can change the file contents. Weird! The ability to write to an immutable file does not follow the manpage promise that immutable files cannot be modified. Worse yet it's inconsistent with the behavior of other syscalls which don't allow modifications of immutable files. Therefore, add the necessary checks to make the write, mmap, and truncate behavior consistent with what the manpage says and consistent with other syscalls on filesystems which support IMMUTABLE. Signed-off-by: Darrick J. Wong --- fs/attr.c | 13 ++++++------- mm/filemap.c | 3 +++ mm/memory.c | 3 +++ mm/mmap.c | 3 +++ 4 files changed, 15 insertions(+), 7 deletions(-) diff --git a/fs/attr.c b/fs/attr.c index d22e8187477f..1fcfdcc5b367 100644 --- a/fs/attr.c +++ b/fs/attr.c @@ -233,19 +233,18 @@ int notify_change(struct dentry * dentry, struct iattr * attr, struct inode **de WARN_ON_ONCE(!inode_is_locked(inode)); - if (ia_valid & (ATTR_MODE | ATTR_UID | ATTR_GID | ATTR_TIMES_SET)) { - if (IS_IMMUTABLE(inode) || IS_APPEND(inode)) - return -EPERM; - } + if (IS_IMMUTABLE(inode)) + return -EPERM; + + if ((ia_valid & (ATTR_MODE | ATTR_UID | ATTR_GID | ATTR_TIMES_SET)) && + IS_APPEND(inode)) + return -EPERM; /* * If utimes(2) and friends are called with times == NULL (or both * times are UTIME_NOW), then we need to check for write permission */ if (ia_valid & ATTR_TOUCH) { - if (IS_IMMUTABLE(inode)) - return -EPERM; - if (!inode_owner_or_capable(inode)) { error = inode_permission(inode, MAY_WRITE); if (error) diff --git a/mm/filemap.c b/mm/filemap.c index d78f577baef2..9fed698f4c63 100644 --- a/mm/filemap.c +++ b/mm/filemap.c @@ -3033,6 +3033,9 @@ inline ssize_t generic_write_checks(struct kiocb *iocb, struct iov_iter *from) loff_t count; int ret; + if (IS_IMMUTABLE(inode)) + return -EPERM; + if (!iov_iter_count(from)) return 0; diff --git a/mm/memory.c b/mm/memory.c index 47fe250307c7..c493db22413a 100644 --- a/mm/memory.c +++ b/mm/memory.c @@ -2148,6 +2148,9 @@ static vm_fault_t do_page_mkwrite(struct vm_fault *vmf) vmf->flags = FAULT_FLAG_WRITE|FAULT_FLAG_MKWRITE; + if (vmf->vma->vm_file && IS_IMMUTABLE(file_inode(vmf->vma->vm_file))) + return VM_FAULT_SIGBUS; + ret = vmf->vma->vm_ops->page_mkwrite(vmf); /* Restore original flags so that caller is not surprised */ vmf->flags = old_flags; diff --git a/mm/mmap.c b/mm/mmap.c index 41eb48d9b527..e49dcbeda461 100644 --- a/mm/mmap.c +++ b/mm/mmap.c @@ -1394,6 +1394,9 @@ unsigned long do_mmap(struct file *file, unsigned long addr, if (!len) return -EINVAL; + if (file && IS_IMMUTABLE(file_inode(file))) + return -EPERM; + /* * Does the application expect PROT_READ to imply PROT_EXEC? *