Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
fork

Configure Feed

Select the types of activity you want to include in your feed.

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>

authored by

Mimi Zohar and committed by
James Morris
acd0c935 e07cccf4

+20 -8
+15 -7
fs/namei.c
··· 1542 1542 * An append-only file must be opened in append mode for writing. 1543 1543 */ 1544 1544 if (IS_APPEND(inode)) { 1545 + error = -EPERM; 1545 1546 if ((flag & FMODE_WRITE) && !(flag & O_APPEND)) 1546 - return -EPERM; 1547 + goto err_out; 1547 1548 if (flag & O_TRUNC) 1548 - return -EPERM; 1549 + goto err_out; 1549 1550 } 1550 1551 1551 1552 /* O_NOATIME can only be set by the owner or superuser */ 1552 1553 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 + } 1555 1558 1556 1559 /* 1557 1560 * Ensure there are no outstanding leases on the file. 1558 1561 */ 1559 1562 error = break_lease(inode, flag); 1560 1563 if (error) 1561 - return error; 1564 + goto err_out; 1562 1565 1563 1566 if (flag & O_TRUNC) { 1564 1567 error = get_write_access(inode); 1565 1568 if (error) 1566 - return error; 1569 + goto err_out; 1567 1570 1568 1571 /* 1569 1572 * Refuse to truncate files with mandatory locks held on them. ··· 1584 1581 } 1585 1582 put_write_access(inode); 1586 1583 if (error) 1587 - return error; 1584 + goto err_out; 1588 1585 } else 1589 1586 if (flag & FMODE_WRITE) 1590 1587 vfs_dq_init(inode); 1591 1588 1592 1589 return 0; 1590 + err_out: 1591 + ima_counts_put(path, acc_mode ? 1592 + acc_mode & (MAY_READ | MAY_WRITE | MAY_EXEC) : 1593 + ACC_MODE(flag) & (MAY_READ | MAY_WRITE)); 1594 + return error; 1593 1595 } 1594 1596 1595 1597 /*
+5 -1
security/integrity/ima/ima_main.c
··· 249 249 struct inode *inode = path->dentry->d_inode; 250 250 struct ima_iint_cache *iint; 251 251 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)) 253 257 return; 254 258 iint = ima_iint_find_insert_get(inode); 255 259 if (!iint)