Skip to content

Commit acd0c93

Browse files
Mimi ZoharJames Morris
authored andcommitted
IMA: update ima_counts_put
- As ima_counts_put() may be called after the inode has been freed, verify that the inode is not NULL, before dereferencing it. - Maintain the IMA file counters in may_open() properly, decrementing any counter increments on subsequent errors. Reported-by: Ciprian Docan <docan@eden.rutgers.edu> Reported-by: J.R. Okajima <hooanon05@yahoo.co.jp> Signed-off-by: Mimi Zohar <zohar@us.ibm.com> Acked-by: Eric Paris <eparis@redhat.com Signed-off-by: James Morris <jmorris@namei.org>
1 parent e07cccf commit acd0c93

File tree

2 files changed

+20
-8
lines changed

2 files changed

+20
-8
lines changed

fs/namei.c

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1542,28 +1542,31 @@ int may_open(struct path *path, int acc_mode, int flag)
15421542
* An append-only file must be opened in append mode for writing.
15431543
*/
15441544
if (IS_APPEND(inode)) {
1545+
error = -EPERM;
15451546
if ((flag & FMODE_WRITE) && !(flag & O_APPEND))
1546-
return -EPERM;
1547+
goto err_out;
15471548
if (flag & O_TRUNC)
1548-
return -EPERM;
1549+
goto err_out;
15491550
}
15501551

15511552
/* O_NOATIME can only be set by the owner or superuser */
15521553
if (flag & O_NOATIME)
1553-
if (!is_owner_or_cap(inode))
1554-
return -EPERM;
1554+
if (!is_owner_or_cap(inode)) {
1555+
error = -EPERM;
1556+
goto err_out;
1557+
}
15551558

15561559
/*
15571560
* Ensure there are no outstanding leases on the file.
15581561
*/
15591562
error = break_lease(inode, flag);
15601563
if (error)
1561-
return error;
1564+
goto err_out;
15621565

15631566
if (flag & O_TRUNC) {
15641567
error = get_write_access(inode);
15651568
if (error)
1566-
return error;
1569+
goto err_out;
15671570

15681571
/*
15691572
* Refuse to truncate files with mandatory locks held on them.
@@ -1581,12 +1584,17 @@ int may_open(struct path *path, int acc_mode, int flag)
15811584
}
15821585
put_write_access(inode);
15831586
if (error)
1584-
return error;
1587+
goto err_out;
15851588
} else
15861589
if (flag & FMODE_WRITE)
15871590
vfs_dq_init(inode);
15881591

15891592
return 0;
1593+
err_out:
1594+
ima_counts_put(path, acc_mode ?
1595+
acc_mode & (MAY_READ | MAY_WRITE | MAY_EXEC) :
1596+
ACC_MODE(flag) & (MAY_READ | MAY_WRITE));
1597+
return error;
15901598
}
15911599

15921600
/*

security/integrity/ima/ima_main.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -249,7 +249,11 @@ void ima_counts_put(struct path *path, int mask)
249249
struct inode *inode = path->dentry->d_inode;
250250
struct ima_iint_cache *iint;
251251

252-
if (!ima_initialized || !S_ISREG(inode->i_mode))
252+
/* The inode may already have been freed, freeing the iint
253+
* with it. Verify the inode is not NULL before dereferencing
254+
* it.
255+
*/
256+
if (!ima_initialized || !inode || !S_ISREG(inode->i_mode))
253257
return;
254258
iint = ima_iint_find_insert_get(inode);
255259
if (!iint)

0 commit comments

Comments
 (0)