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 | |
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')
-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 f0053552fd58..68efe3b8d993 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 6e8cb931b8f1..69b4856af4da 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); |