mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-12-28 16:56:26 +00:00
ima: detect changes to the backing overlay file
commitb836c4d29f
upstream. Commit18b44bc5a6
("ovl: Always reevaluate the file signature for IMA") forced signature re-evaulation on every file access. Instead of always re-evaluating the file's integrity, detect a change to the backing file, by comparing the cached file metadata with the backing file's metadata. Verifying just the i_version has not changed is insufficient. In addition save and compare the i_ino and s_dev as well. Reviewed-by: Amir Goldstein <amir73il@gmail.com> Tested-by: Eric Snowberg <eric.snowberg@oracle.com> Tested-by: Raul E Rangel <rrangel@chromium.org> Cc: stable@vger.kernel.org Signed-off-by: Mimi Zohar <zohar@linux.ibm.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
f2f0144e82
commit
0d29174959
@ -1467,7 +1467,7 @@ int ovl_fill_super(struct super_block *sb, struct fs_context *fc)
|
||||
ovl_trusted_xattr_handlers;
|
||||
sb->s_fs_info = ofs;
|
||||
sb->s_flags |= SB_POSIXACL;
|
||||
sb->s_iflags |= SB_I_SKIP_SYNC | SB_I_IMA_UNVERIFIABLE_SIGNATURE;
|
||||
sb->s_iflags |= SB_I_SKIP_SYNC;
|
||||
|
||||
err = -ENOMEM;
|
||||
root_dentry = ovl_get_root(sb, ctx->upper.dentry, oe);
|
||||
|
@ -243,6 +243,7 @@ int ima_collect_measurement(struct integrity_iint_cache *iint,
|
||||
{
|
||||
const char *audit_cause = "failed";
|
||||
struct inode *inode = file_inode(file);
|
||||
struct inode *real_inode = d_real_inode(file_dentry(file));
|
||||
const char *filename = file->f_path.dentry->d_name.name;
|
||||
struct ima_max_digest_data hash;
|
||||
struct kstat stat;
|
||||
@ -302,6 +303,10 @@ int ima_collect_measurement(struct integrity_iint_cache *iint,
|
||||
iint->ima_hash = tmpbuf;
|
||||
memcpy(iint->ima_hash, &hash, length);
|
||||
iint->version = i_version;
|
||||
if (real_inode != inode) {
|
||||
iint->real_ino = real_inode->i_ino;
|
||||
iint->real_dev = real_inode->i_sb->s_dev;
|
||||
}
|
||||
|
||||
/* Possibly temporary failure due to type of read (eg. O_DIRECT) */
|
||||
if (!result)
|
||||
|
@ -25,6 +25,7 @@
|
||||
#include <linux/xattr.h>
|
||||
#include <linux/ima.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/iversion.h>
|
||||
|
||||
#include "ima.h"
|
||||
|
||||
@ -207,7 +208,7 @@ static int process_measurement(struct file *file, const struct cred *cred,
|
||||
u32 secid, char *buf, loff_t size, int mask,
|
||||
enum ima_hooks func)
|
||||
{
|
||||
struct inode *inode = file_inode(file);
|
||||
struct inode *backing_inode, *inode = file_inode(file);
|
||||
struct integrity_iint_cache *iint = NULL;
|
||||
struct ima_template_desc *template_desc = NULL;
|
||||
char *pathbuf = NULL;
|
||||
@ -284,6 +285,19 @@ static int process_measurement(struct file *file, const struct cred *cred,
|
||||
iint->measured_pcrs = 0;
|
||||
}
|
||||
|
||||
/* Detect and re-evaluate changes made to the backing file. */
|
||||
backing_inode = d_real_inode(file_dentry(file));
|
||||
if (backing_inode != inode &&
|
||||
(action & IMA_DO_MASK) && (iint->flags & IMA_DONE_MASK)) {
|
||||
if (!IS_I_VERSION(backing_inode) ||
|
||||
backing_inode->i_sb->s_dev != iint->real_dev ||
|
||||
backing_inode->i_ino != iint->real_ino ||
|
||||
!inode_eq_iversion(backing_inode, iint->version)) {
|
||||
iint->flags &= ~IMA_DONE_MASK;
|
||||
iint->measured_pcrs = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Determine if already appraised/measured based on bitmask
|
||||
* (IMA_MEASURE, IMA_MEASURED, IMA_XXXX_APPRAISE, IMA_XXXX_APPRAISED,
|
||||
* IMA_AUDIT, IMA_AUDITED)
|
||||
|
@ -164,6 +164,8 @@ struct integrity_iint_cache {
|
||||
unsigned long flags;
|
||||
unsigned long measured_pcrs;
|
||||
unsigned long atomic_flags;
|
||||
unsigned long real_ino;
|
||||
dev_t real_dev;
|
||||
enum integrity_status ima_file_status:4;
|
||||
enum integrity_status ima_mmap_status:4;
|
||||
enum integrity_status ima_bprm_status:4;
|
||||
|
Loading…
Reference in New Issue
Block a user