On Wed, 2006-02-22 at 10:07 -0500, Stephen Smalley wrote:
On Tue, 2006-02-21 at 17:59 -0600, Darrel Goeddel wrote:
> - Add a selinux callback for re-initializing the se_rule field when there is
> a policy reload. THIS NEEDS WORK - It doesn't obey proper locking yet, but
> it is functional. I need to get my head around the locking of the audit
> structures a little better - I'll also take suggestions ;)
<snip>
> @@ -726,3 +777,45 @@ unlock_and_return:
> rcu_read_unlock();
> return result;
> }
> +
> +static int selinux_callback(void)
> +{
> + struct audit_entry *entry;
> + int i, j, err = 0;
> +
> + /* TODO: add proper locking. */
> + for (i = 0; i < AUDIT_NR_FILTERS; i++) {
> + list_for_each_entry(entry, &audit_filter_list[i], list) {
> + for (j = 0; j < entry->rule.field_count; j++) {
> + struct audit_field *f = &entry->rule.fields[j];
> + switch (f->type) {
> + case AUDIT_SE_USER:
> + case AUDIT_SE_ROLE:
> + case AUDIT_SE_TYPE:
> + case AUDIT_SE_SEN:
> + case AUDIT_SE_CLR:
> + selinux_audit_rule_free(f->se_rule);
> + err = selinux_audit_rule_init(f->type,
> + f->op, f->se_str, &f->se_rule);
> + if (err == -EINVAL) {
> + printk(KERN_WARNING "selinux audit rule for item %s is invalid\n",
f->se_str);
> + err = 0;
> + }
> + if (err)
> + goto out;
> + }
> + }
> + }
> + }
For RCU, you need to make a new copy of the entry, mutate the copy (not
the original), list_replace_rcu the old original with the modified copy,
and call_rcu to drop the original when it is safe to do so. Look at the
SELinux AVC code for an example (avc_update_node).
Oh, and it looks like you should be holding the audit_netlink_mutex as
well to synchronize with adding, removing and listing of rules. That is
easy though - the harder part is grasping the RCU model.
Documentation/RCU is very helpful.
--
Stephen Smalley
National Security Agency