diff options
| author | Mimi Zohar <zohar@linux.vnet.ibm.com> | 2010-11-02 10:13:07 -0400 |
|---|---|---|
| committer | Mimi Zohar <zohar@linux.vnet.ibm.com> | 2011-02-10 07:51:44 -0500 |
| commit | 890275b5eb79e9933d12290473eab9ac38da0051 (patch) | |
| tree | 8fa529a6fdfa7647ed4e14287658b71df8636ddd /security/integrity | |
| parent | a5c96ebf1d71df0c5fb77ab58c9aeb307cf02372 (diff) | |
IMA: maintain i_readcount in the VFS layer
ima_counts_get() updated the readcount and invalidated the PCR,
as necessary. Only update the i_readcount in the VFS layer.
Move the PCR invalidation checks to ima_file_check(), where it
belongs.
Maintaining the i_readcount in the VFS layer, will allow other
subsystems to use i_readcount.
Signed-off-by: Mimi Zohar <zohar@us.ibm.com>
Acked-by: Eric Paris <eparis@redhat.com>
Diffstat (limited to 'security/integrity')
| -rw-r--r-- | security/integrity/ima/ima_iint.c | 2 | ||||
| -rw-r--r-- | security/integrity/ima/ima_main.c | 25 |
2 files changed, 8 insertions, 19 deletions
diff --git a/security/integrity/ima/ima_iint.c b/security/integrity/ima/ima_iint.c index f0053552fd5..68efe3b8d99 100644 --- a/security/integrity/ima/ima_iint.c +++ b/security/integrity/ima/ima_iint.c | |||
| @@ -141,8 +141,6 @@ void ima_inode_free(struct inode *inode) | |||
| 141 | printk(KERN_INFO "%s: readcount: %u\n", __func__, | 141 | printk(KERN_INFO "%s: readcount: %u\n", __func__, |
| 142 | atomic_read(&inode->i_readcount)); | 142 | atomic_read(&inode->i_readcount)); |
| 143 | 143 | ||
| 144 | atomic_set(&inode->i_readcount, 0); | ||
| 145 | |||
| 146 | if (!IS_IMA(inode)) | 144 | if (!IS_IMA(inode)) |
| 147 | return; | 145 | return; |
| 148 | 146 | ||
diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c index 6e8cb931b8f..69b4856af4d 100644 --- a/security/integrity/ima/ima_main.c +++ b/security/integrity/ima/ima_main.c | |||
| @@ -86,17 +86,16 @@ out: | |||
| 86 | } | 86 | } |
| 87 | 87 | ||
| 88 | /* | 88 | /* |
| 89 | * ima_counts_get - increment file counts | 89 | * ima_rdwr_violation_check |
| 90 | * | 90 | * |
| 91 | * Maintain read/write counters for all files, but only | 91 | * Only invalidate the PCR for measured files: |
| 92 | * invalidate the PCR for measured files: | ||
| 93 | * - Opening a file for write when already open for read, | 92 | * - Opening a file for write when already open for read, |
| 94 | * results in a time of measure, time of use (ToMToU) error. | 93 | * results in a time of measure, time of use (ToMToU) error. |
| 95 | * - Opening a file for read when already open for write, | 94 | * - Opening a file for read when already open for write, |
| 96 | * could result in a file measurement error. | 95 | * could result in a file measurement error. |
| 97 | * | 96 | * |
| 98 | */ | 97 | */ |
| 99 | void ima_counts_get(struct file *file) | 98 | static void ima_rdwr_violation_check(struct file *file) |
| 100 | { | 99 | { |
| 101 | struct dentry *dentry = file->f_path.dentry; | 100 | struct dentry *dentry = file->f_path.dentry; |
| 102 | struct inode *inode = dentry->d_inode; | 101 | struct inode *inode = dentry->d_inode; |
| @@ -104,13 +103,10 @@ void ima_counts_get(struct file *file) | |||
| 104 | int rc; | 103 | int rc; |
| 105 | bool send_tomtou = false, send_writers = false; | 104 | bool send_tomtou = false, send_writers = false; |
| 106 | 105 | ||
| 107 | if (!S_ISREG(inode->i_mode)) | 106 | if (!S_ISREG(inode->i_mode) || !ima_initialized) |
| 108 | return; | 107 | return; |
| 109 | 108 | ||
| 110 | spin_lock(&inode->i_lock); | 109 | mutex_lock(&inode->i_mutex); /* file metadata: permissions, xattr */ |
| 111 | |||
| 112 | if (!ima_initialized) | ||
| 113 | goto out; | ||
| 114 | 110 | ||
| 115 | if (mode & FMODE_WRITE) { | 111 | if (mode & FMODE_WRITE) { |
| 116 | if (atomic_read(&inode->i_readcount) && IS_IMA(inode)) | 112 | if (atomic_read(&inode->i_readcount) && IS_IMA(inode)) |
| @@ -125,11 +121,7 @@ void ima_counts_get(struct file *file) | |||
| 125 | if (atomic_read(&inode->i_writecount) > 0) | 121 | if (atomic_read(&inode->i_writecount) > 0) |
| 126 | send_writers = true; | 122 | send_writers = true; |
| 127 | out: | 123 | out: |
| 128 | /* remember the vfs deals with i_writecount */ | 124 | mutex_unlock(&inode->i_mutex); |
| 129 | if ((mode & (FMODE_READ | FMODE_WRITE)) == FMODE_READ) | ||
| 130 | atomic_inc(&inode->i_readcount); | ||
| 131 | |||
| 132 | spin_unlock(&inode->i_lock); | ||
| 133 | 125 | ||
| 134 | if (send_tomtou) | 126 | if (send_tomtou) |
| 135 | ima_add_violation(inode, dentry->d_name.name, "invalid_pcr", | 127 | ima_add_violation(inode, dentry->d_name.name, "invalid_pcr", |
| @@ -158,7 +150,6 @@ static void ima_dec_counts(struct inode *inode, struct file *file) | |||
| 158 | } | 150 | } |
| 159 | return; | 151 | return; |
| 160 | } | 152 | } |
| 161 | atomic_dec(&inode->i_readcount); | ||
| 162 | } | 153 | } |
| 163 | } | 154 | } |
| 164 | 155 | ||
| @@ -203,8 +194,7 @@ static void ima_file_free_noiint(struct inode *inode, struct file *file) | |||
| 203 | * ima_file_free - called on __fput() | 194 | * ima_file_free - called on __fput() |
| 204 | * @file: pointer to file structure being freed | 195 | * @file: pointer to file structure being freed |
| 205 | * | 196 | * |
| 206 | * Flag files that changed, based on i_version; | 197 | * Flag files that changed, based on i_version |
| 207 | * and decrement the i_readcount. | ||
| 208 | */ | 198 | */ |
| 209 | void ima_file_free(struct file *file) | 199 | void ima_file_free(struct file *file) |
| 210 | { | 200 | { |
| @@ -318,6 +308,7 @@ int ima_file_check(struct file *file, int mask) | |||
| 318 | { | 308 | { |
| 319 | int rc; | 309 | int rc; |
| 320 | 310 | ||
| 311 | ima_rdwr_violation_check(file); | ||
| 321 | rc = process_measurement(file, file->f_dentry->d_name.name, | 312 | rc = process_measurement(file, file->f_dentry->d_name.name, |
| 322 | mask & (MAY_READ | MAY_WRITE | MAY_EXEC), | 313 | mask & (MAY_READ | MAY_WRITE | MAY_EXEC), |
| 323 | FILE_CHECK); | 314 | FILE_CHECK); |
