From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from e23smtp04.au.ibm.com ([202.81.31.146]:43535 "EHLO e23smtp04.au.ibm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751301AbcBPUz0 (ORCPT ); Tue, 16 Feb 2016 15:55:26 -0500 Received: from localhost by e23smtp04.au.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Wed, 17 Feb 2016 06:55:24 +1000 From: Mimi Zohar To: linux-security-module Cc: Dmitry Kasatkin , Al Viro , "Luis R. Rodriguez" , Kees Cook , Dave Young , linux-fsdevel@vger.kernel.org, Dmitry Kasatkin , Mimi Zohar Subject: [PATCH] vfs: forbid write access when reading a file into memory Date: Tue, 16 Feb 2016 15:54:05 -0500 Message-Id: <1455656045-21463-1-git-send-email-zohar@linux.vnet.ibm.com> Sender: linux-fsdevel-owner@vger.kernel.org List-ID: From: Dmitry Kasatkin This patch is based on top of the "vfs: support for a common kernel file loader" patch set. In general when the kernel is reading a file into memory it does not want anything else writing to it. The kernel currently only forbids write access to a file being executed. This patch extends this locking to files being read by the kernel. Changelog: - moved function to kernel_read_file() - Mimi - updated patch description - Mimi Signed-off-by: Dmitry Kasatkin Cc: Al Viro Signed-off-by: Mimi Zohar --- fs/exec.c | 29 +++++++++++++++++++++-------- 1 file changed, 21 insertions(+), 8 deletions(-) diff --git a/fs/exec.c b/fs/exec.c index 604f669..1b7d617 100644 --- a/fs/exec.c +++ b/fs/exec.c @@ -846,15 +846,25 @@ int kernel_read_file(struct file *file, void **buf, loff_t *size, if (ret) return ret; + ret = deny_write_access(file); + if (ret) + return ret; + i_size = i_size_read(file_inode(file)); - if (max_size > 0 && i_size > max_size) - return -EFBIG; - if (i_size <= 0) - return -EINVAL; + if (max_size > 0 && i_size > max_size) { + ret = -EFBIG; + goto out; + } + if (i_size <= 0) { + ret = -EINVAL; + goto out; + } *buf = vmalloc(i_size); - if (!*buf) - return -ENOMEM; + if (!*buf) { + ret = -ENOMEM; + goto out; + } pos = 0; while (pos < i_size) { @@ -872,18 +882,21 @@ int kernel_read_file(struct file *file, void **buf, loff_t *size, if (pos != i_size) { ret = -EIO; - goto out; + goto out_free; } ret = security_kernel_post_read_file(file, *buf, i_size, id); if (!ret) *size = pos; -out: +out_free: if (ret < 0) { vfree(*buf); *buf = NULL; } + +out: + allow_write_access(file); return ret; } EXPORT_SYMBOL_GPL(kernel_read_file); -- 2.1.0