Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 217417
b: refs/heads/master
c: a178d20
h: refs/heads/master
i:
  217415: 2d44184
v: v3
  • Loading branch information
Eric Paris authored and Linus Torvalds committed Oct 26, 2010
1 parent 9f6a9e7 commit 404961a
Show file tree
Hide file tree
Showing 7 changed files with 23 additions and 35 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: b9593d309d17c57e9ddc3934d641902533896ca9
refs/heads/master: a178d2027d3198b0a04517d764326ab71cd73da2
1 change: 1 addition & 0 deletions trunk/fs/inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
#include <linux/mount.h>
#include <linux/async.h>
#include <linux/posix_acl.h>
#include <linux/ima.h>

/*
* This is needed for the following functions:
Expand Down
4 changes: 4 additions & 0 deletions trunk/include/linux/fs.h
Original file line number Diff line number Diff line change
Expand Up @@ -776,6 +776,10 @@ struct inode {

unsigned int i_flags;

#ifdef CONFIG_IMA
/* protected by i_lock */
unsigned int i_readcount; /* struct files open RO */
#endif
atomic_t i_writecount;
#ifdef CONFIG_SECURITY
void *i_security;
Expand Down
3 changes: 1 addition & 2 deletions trunk/security/integrity/ima/ima.h
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ int ima_init(void);
void ima_cleanup(void);
int ima_fs_init(void);
void ima_fs_cleanup(void);
int ima_inode_alloc(struct inode *inode);
int ima_add_template_entry(struct ima_template_entry *entry, int violation,
const char *op, struct inode *inode);
int ima_calc_hash(struct file *file, char *digest);
Expand Down Expand Up @@ -106,8 +107,6 @@ struct ima_iint_cache {
unsigned char flags;
u8 digest[IMA_DIGEST_SIZE];
struct mutex mutex; /* protects: version, flags, digest */
/* protected by inode->i_lock */
unsigned int readcount; /* measured files readcount */
struct kref refcount; /* ima_iint_cache reference count */
};

Expand Down
2 changes: 1 addition & 1 deletion trunk/security/integrity/ima/ima_api.c
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ int ima_must_measure(struct ima_iint_cache *iint, struct inode *inode,
{
int must_measure;

if (iint->flags & IMA_MEASURED)
if (iint && iint->flags & IMA_MEASURED)
return 1;

must_measure = ima_match_policy(inode, function, mask);
Expand Down
11 changes: 5 additions & 6 deletions trunk/security/integrity/ima/ima_iint.c
Original file line number Diff line number Diff line change
Expand Up @@ -124,11 +124,6 @@ void iint_free(struct kref *kref)
refcount);
iint->version = 0;
iint->flags = 0UL;
if (iint->readcount != 0) {
printk(KERN_INFO "%s: readcount: %u\n", __func__,
iint->readcount);
iint->readcount = 0;
}
kref_init(&iint->refcount);
kmem_cache_free(iint_cache, iint);
}
Expand All @@ -143,6 +138,11 @@ void ima_inode_free(struct inode *inode)
{
struct ima_iint_cache *iint;

if (inode->i_readcount)
printk(KERN_INFO "%s: readcount: %u\n", __func__, inode->i_readcount);

inode->i_readcount = 0;

spin_lock(&ima_iint_lock);
iint = __ima_iint_find(inode);
if (iint)
Expand All @@ -160,7 +160,6 @@ static void init_once(void *foo)
iint->version = 0;
iint->flags = 0UL;
mutex_init(&iint->mutex);
iint->readcount = 0;
kref_init(&iint->refcount);
}

Expand Down
35 changes: 10 additions & 25 deletions trunk/security/integrity/ima/ima_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -85,17 +85,6 @@ static bool ima_limit_imbalance(struct file *file)
return found;
}

/*
* Update the counts given an fmode_t
*/
static void ima_inc_counts(struct ima_iint_cache *iint, fmode_t mode)
{
assert_spin_locked(&iint->inode->i_lock);

if ((mode & (FMODE_READ | FMODE_WRITE)) == FMODE_READ)
iint->readcount++;
}

/*
* ima_counts_get - increment file counts
*
Expand All @@ -112,38 +101,34 @@ void ima_counts_get(struct file *file)
struct dentry *dentry = file->f_path.dentry;
struct inode *inode = dentry->d_inode;
fmode_t mode = file->f_mode;
struct ima_iint_cache *iint;
int rc;
bool send_tomtou = false, send_writers = false;

if (!iint_initialized || !S_ISREG(inode->i_mode))
if (!S_ISREG(inode->i_mode))
return;
iint = ima_iint_find_get(inode);
if (!iint)
return;
mutex_lock(&iint->mutex);

spin_lock(&inode->i_lock);

if (!ima_initialized)
goto out;

rc = ima_must_measure(iint, inode, MAY_READ, FILE_CHECK);
rc = ima_must_measure(NULL, inode, MAY_READ, FILE_CHECK);
if (rc < 0)
goto out;

if (mode & FMODE_WRITE) {
if (iint->readcount)
if (inode->i_readcount)
send_tomtou = true;
goto out;
}

if (atomic_read(&inode->i_writecount) > 0)
send_writers = true;
out:
ima_inc_counts(iint, file->f_mode);
/* remember the vfs deals with i_writecount */
if ((mode & (FMODE_READ | FMODE_WRITE)) == FMODE_READ)
inode->i_readcount++;
spin_unlock(&inode->i_lock);
mutex_unlock(&iint->mutex);
kref_put(&iint->refcount, iint_free);

if (send_tomtou)
ima_add_violation(inode, dentry->d_name.name, "invalid_pcr",
Expand All @@ -166,9 +151,9 @@ static void ima_dec_counts(struct ima_iint_cache *iint, struct inode *inode,
assert_spin_locked(&inode->i_lock);

if ((mode & (FMODE_READ | FMODE_WRITE)) == FMODE_READ) {
if (unlikely(iint->readcount == 0))
if (unlikely(inode->i_readcount == 0))
dump = true;
iint->readcount--;
inode->i_readcount--;
}
if (mode & FMODE_WRITE) {
if (atomic_read(&inode->i_writecount) <= 0)
Expand All @@ -180,7 +165,7 @@ static void ima_dec_counts(struct ima_iint_cache *iint, struct inode *inode,

if (dump && !ima_limit_imbalance(file)) {
printk(KERN_INFO "%s: open/free imbalance (r:%u)\n",
__func__, iint->readcount);
__func__, inode->i_readcount);
dump_stack();
}
}
Expand Down

0 comments on commit 404961a

Please sign in to comment.