Skip to content

Commit 1e5df00

Browse files
mimizoharsmb49
authored andcommitted
ima: detect changes to the backing overlay file
BugLink: https://bugs.launchpad.net/bugs/2050038 commit b836c4d upstream. Commit 18b44bc ("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> Signed-off-by: Portia Stephens <portia.stephens@canonical.com> Signed-off-by: Stefan Bader <stefan.bader@canonical.com>
1 parent ddc2f88 commit 1e5df00

File tree

4 files changed

+23
-2
lines changed

4 files changed

+23
-2
lines changed

fs/overlayfs/super.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2141,7 +2141,7 @@ static int ovl_fill_super(struct super_block *sb, void *data, int silent)
21412141
ovl_trusted_xattr_handlers;
21422142
sb->s_fs_info = ofs;
21432143
sb->s_flags |= SB_POSIXACL;
2144-
sb->s_iflags |= SB_I_SKIP_SYNC | SB_I_IMA_UNVERIFIABLE_SIGNATURE;
2144+
sb->s_iflags |= SB_I_SKIP_SYNC;
21452145

21462146
err = -ENOMEM;
21472147
root_dentry = ovl_get_root(sb, upperpath.dentry, oe);

security/integrity/ima/ima_api.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,7 @@ int ima_collect_measurement(struct integrity_iint_cache *iint,
216216
{
217217
const char *audit_cause = "failed";
218218
struct inode *inode = file_inode(file);
219+
struct inode *real_inode = d_real_inode(file_dentry(file));
219220
const char *filename = file->f_path.dentry->d_name.name;
220221
int result = 0;
221222
int length;
@@ -266,6 +267,10 @@ int ima_collect_measurement(struct integrity_iint_cache *iint,
266267
iint->ima_hash = tmpbuf;
267268
memcpy(iint->ima_hash, &hash, length);
268269
iint->version = i_version;
270+
if (real_inode != inode) {
271+
iint->real_ino = real_inode->i_ino;
272+
iint->real_dev = real_inode->i_sb->s_dev;
273+
}
269274

270275
/* Possibly temporary failure due to type of read (eg. O_DIRECT) */
271276
if (!result)

security/integrity/ima/ima_main.c

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
#include <linux/ima.h>
2727
#include <linux/iversion.h>
2828
#include <linux/fs.h>
29+
#include <linux/iversion.h>
2930

3031
#include "ima.h"
3132

@@ -202,7 +203,7 @@ static int process_measurement(struct file *file, const struct cred *cred,
202203
struct lsmblob *blob, char *buf, loff_t size,
203204
int mask, enum ima_hooks func)
204205
{
205-
struct inode *inode = file_inode(file);
206+
struct inode *backing_inode, *inode = file_inode(file);
206207
struct integrity_iint_cache *iint = NULL;
207208
struct ima_template_desc *template_desc = NULL;
208209
char *pathbuf = NULL;
@@ -278,6 +279,19 @@ static int process_measurement(struct file *file, const struct cred *cred,
278279
iint->measured_pcrs = 0;
279280
}
280281

282+
/* Detect and re-evaluate changes made to the backing file. */
283+
backing_inode = d_real_inode(file_dentry(file));
284+
if (backing_inode != inode &&
285+
(action & IMA_DO_MASK) && (iint->flags & IMA_DONE_MASK)) {
286+
if (!IS_I_VERSION(backing_inode) ||
287+
backing_inode->i_sb->s_dev != iint->real_dev ||
288+
backing_inode->i_ino != iint->real_ino ||
289+
!inode_eq_iversion(backing_inode, iint->version)) {
290+
iint->flags &= ~IMA_DONE_MASK;
291+
iint->measured_pcrs = 0;
292+
}
293+
}
294+
281295
/* Determine if already appraised/measured based on bitmask
282296
* (IMA_MEASURE, IMA_MEASURED, IMA_XXXX_APPRAISE, IMA_XXXX_APPRAISED,
283297
* IMA_AUDIT, IMA_AUDITED)

security/integrity/integrity.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,8 @@ struct integrity_iint_cache {
131131
unsigned long flags;
132132
unsigned long measured_pcrs;
133133
unsigned long atomic_flags;
134+
unsigned long real_ino;
135+
dev_t real_dev;
134136
enum integrity_status ima_file_status:4;
135137
enum integrity_status ima_mmap_status:4;
136138
enum integrity_status ima_bprm_status:4;

0 commit comments

Comments
 (0)