Skip to content

Commit 0716abb

Browse files
Dmitry KasatkinMimi Zohar
authored andcommitted
ima: use atomic bit operations to protect policy update interface
The current implementation uses an atomic counter to provide exclusive access to the sysfs 'policy' entry to update the IMA policy. While it is highly unlikely, the usage of a counter might potentially allow another process to overflow the counter, open the interface and insert additional rules into the policy being loaded. This patch replaces using an atomic counter with atomic bit operations which is more reliable and a widely used method to provide exclusive access. As bit operation keep the interface locked after successful update, it makes it unnecessary to verify if the default policy was set or not during parsing and interface closing. This patch also removes that code. Changes in v3: * move audit log message to ima_relead_policy() to report successful and unsuccessful result * unnecessary comment removed Changes in v2: * keep interface locked after successful policy load as in original design * remove sysfs entry as in original design Signed-off-by: Dmitry Kasatkin <[email protected]> Signed-off-by: Mimi Zohar <[email protected]>
1 parent 7178784 commit 0716abb

File tree

2 files changed

+18
-28
lines changed

2 files changed

+18
-28
lines changed

security/integrity/ima/ima_fs.c

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -288,7 +288,12 @@ static struct dentry *runtime_measurements_count;
288288
static struct dentry *violations;
289289
static struct dentry *ima_policy;
290290

291-
static atomic_t policy_opencount = ATOMIC_INIT(1);
291+
enum ima_fs_flags {
292+
IMA_FS_BUSY,
293+
};
294+
295+
static unsigned long ima_fs_flags;
296+
292297
/*
293298
* ima_open_policy: sequentialize access to the policy file
294299
*/
@@ -297,9 +302,9 @@ static int ima_open_policy(struct inode *inode, struct file *filp)
297302
/* No point in being allowed to open it if you aren't going to write */
298303
if (!(filp->f_flags & O_WRONLY))
299304
return -EACCES;
300-
if (atomic_dec_and_test(&policy_opencount))
301-
return 0;
302-
return -EBUSY;
305+
if (test_and_set_bit(IMA_FS_BUSY, &ima_fs_flags))
306+
return -EBUSY;
307+
return 0;
303308
}
304309

305310
/*
@@ -311,12 +316,16 @@ static int ima_open_policy(struct inode *inode, struct file *filp)
311316
*/
312317
static int ima_release_policy(struct inode *inode, struct file *file)
313318
{
314-
pr_info("IMA: policy update %s\n",
315-
valid_policy ? "completed" : "failed");
319+
const char *cause = valid_policy ? "completed" : "failed";
320+
321+
pr_info("IMA: policy update %s\n", cause);
322+
integrity_audit_msg(AUDIT_INTEGRITY_STATUS, NULL, NULL,
323+
"policy_update", cause, !valid_policy, 0);
324+
316325
if (!valid_policy) {
317326
ima_delete_rules();
318327
valid_policy = 1;
319-
atomic_set(&policy_opencount, 1);
328+
clear_bit(IMA_FS_BUSY, &ima_fs_flags);
320329
return 0;
321330
}
322331
ima_update_policy();

security/integrity/ima/ima_policy.c

Lines changed: 2 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -356,19 +356,8 @@ void __init ima_init_policy(void)
356356
*/
357357
void ima_update_policy(void)
358358
{
359-
static const char op[] = "policy_update";
360-
const char *cause = "already-exists";
361-
int result = 1;
362-
int audit_info = 0;
363-
364-
if (ima_rules == &ima_default_rules) {
365-
ima_rules = &ima_policy_rules;
366-
ima_update_policy_flag();
367-
cause = "complete";
368-
result = 0;
369-
}
370-
integrity_audit_msg(AUDIT_INTEGRITY_STATUS, NULL,
371-
NULL, op, cause, result, audit_info);
359+
ima_rules = &ima_policy_rules;
360+
ima_update_policy_flag();
372361
}
373362

374363
enum {
@@ -686,14 +675,6 @@ ssize_t ima_parse_add_rule(char *rule)
686675
ssize_t result, len;
687676
int audit_info = 0;
688677

689-
/* Prevent installed policy from changing */
690-
if (ima_rules != &ima_default_rules) {
691-
integrity_audit_msg(AUDIT_INTEGRITY_STATUS, NULL,
692-
NULL, op, "already-exists",
693-
-EACCES, audit_info);
694-
return -EACCES;
695-
}
696-
697678
p = strsep(&rule, "\n");
698679
len = strlen(p) + 1;
699680
p += strspn(p, " \t");

0 commit comments

Comments
 (0)