From patchwork Tue Mar 3 10:38:38 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jan Kara X-Patchwork-Id: 5921121 Return-Path: X-Original-To: patchwork-linux-fsdevel@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork1.web.kernel.org (Postfix) with ESMTP id B94299FB14 for ; Tue, 3 Mar 2015 10:38:55 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id EDAF8202B4 for ; Tue, 3 Mar 2015 10:38:53 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 09EF12012E for ; Tue, 3 Mar 2015 10:38:53 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1756110AbbCCKiu (ORCPT ); Tue, 3 Mar 2015 05:38:50 -0500 Received: from cantor2.suse.de ([195.135.220.15]:58878 "EHLO mx2.suse.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1755221AbbCCKis (ORCPT ); Tue, 3 Mar 2015 05:38:48 -0500 X-Virus-Scanned: by amavisd-new at test-mx.suse.de Received: from relay1.suse.de (charybdis-ext.suse.de [195.135.220.254]) by mx2.suse.de (Postfix) with ESMTP id 766EAAEAE; Tue, 3 Mar 2015 10:38:46 +0000 (UTC) Received: by quack.suse.cz (Postfix, from userid 1000) id 174FF82752; Tue, 3 Mar 2015 11:38:43 +0100 (CET) From: Jan Kara To: Al Viro Cc: linux-fsdevel@vger.kernel.org, xfs@oss.sgi.com, Jan Kara Subject: [PATCH 4/5] fs: Call security_ops->inode_killpriv on truncate Date: Tue, 3 Mar 2015 11:38:38 +0100 Message-Id: <1425379119-3773-5-git-send-email-jack@suse.cz> X-Mailer: git-send-email 2.1.4 In-Reply-To: <1425379119-3773-1-git-send-email-jack@suse.cz> References: <1425379119-3773-1-git-send-email-jack@suse.cz> Sender: linux-fsdevel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org X-Spam-Status: No, score=-6.9 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, T_RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Comment in include/linux/security.h says that ->inode_killpriv() should be called when setuid bit is being removed and that similar security labels should be removed at this time as well. However we don't call ->inode_killpriv() when we remove suid bit on truncate. We fix the problem by calling ->inode_need_killpriv() and subsequently ->inode_killpriv() on truncate the same way as we do it on file write. After this patch there's only one user of should_remove_suid() - ocfs2 - and indeed it's buggy because it doesn't clear security attributes on write. However fixing it is difficult because of special locking constraints. Signed-off-by: Jan Kara --- fs/inode.c | 5 ++--- fs/open.c | 6 ++++-- include/linux/fs.h | 6 +++++- 3 files changed, 11 insertions(+), 6 deletions(-) diff --git a/fs/inode.c b/fs/inode.c index 3407bedc1c7b..7f4eabd72bd6 100644 --- a/fs/inode.c +++ b/fs/inode.c @@ -1665,9 +1665,8 @@ EXPORT_SYMBOL(should_remove_suid); * response to write or truncate. Return 0 if nothing has to be changed. * Negative value on error (change should be denied). */ -int file_needs_remove_privs(struct file *file) +int dentry_needs_remove_privs(struct dentry *dentry) { - struct dentry *dentry = file->f_path.dentry; struct inode *inode = dentry->d_inode; int mask = 0; int ret; @@ -1683,7 +1682,7 @@ int file_needs_remove_privs(struct file *file) mask |= ATTR_KILL_PRIV; return mask; } -EXPORT_SYMBOL(file_needs_remove_privs); +EXPORT_SYMBOL(dentry_needs_remove_privs); static int __remove_privs(struct dentry *dentry, int kill) { diff --git a/fs/open.c b/fs/open.c index 33f9cbf2610b..14e2aeea4cee 100644 --- a/fs/open.c +++ b/fs/open.c @@ -51,8 +51,10 @@ int do_truncate(struct dentry *dentry, loff_t length, unsigned int time_attrs, newattrs.ia_valid |= ATTR_FILE; } - /* Remove suid/sgid on truncate too */ - ret = should_remove_suid(dentry); + /* Remove suid/sgid and security markings on truncate too */ + ret = dentry_needs_remove_privs(dentry); + if (ret < 0) + return ret; if (ret) newattrs.ia_valid |= ret | ATTR_FORCE; diff --git a/include/linux/fs.h b/include/linux/fs.h index 78ff19f0c323..ddaceede20ad 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -2518,7 +2518,11 @@ extern struct inode *new_inode(struct super_block *sb); extern void free_inode_nonrcu(struct inode *inode); extern int should_remove_suid(struct dentry *); extern int file_remove_privs(struct file *); -extern int file_needs_remove_privs(struct file *file); +extern int dentry_needs_remove_privs(struct dentry *dentry); +static inline int file_needs_remove_privs(struct file *file) +{ + return dentry_needs_remove_privs(file->f_path.dentry); +} extern void __insert_inode_hash(struct inode *, unsigned long hashval); static inline void insert_inode_hash(struct inode *inode)