History

smack: Implement the watch_key and post_notification hooks

Implement the watch_key security hook in Smack to make sure that a key grants the caller Read permission in order to set a watch on a key. Also implement the post_notification security hook to make sure that the notification source is granted Write permission by the watch queue. For the moment, the watch_devices security hook is left unimplemented as it's not obvious what the object should be since the queue is global and didn't previously exist.

David Howells committed 6 years ago

Commit a8478a61 parent 3e412cc2 files · +83 −1Browse files

Unified · Split

2 files
  1. include/linux/lsm_audit.h +1 −0
  2. security/smack/smack_lsm.c +82 −1
include/linux/lsm_audit.h+1−0
@@ -75,6 +75,7 @@ struct common_audit_data { · 74 unmodified lines
7575 #define LSM_AUDIT_DATA_IBPKEY 13
7676 #define LSM_AUDIT_DATA_IBENDPORT 14
7777 #define LSM_AUDIT_DATA_LOCKDOWN 15
78+#define LSM_AUDIT_DATA_NOTIFICATION 16
7879 union {
7980 struct path path;
8081 struct dentry *dentry;
security/smack/smack_lsm.c+82−1
@@ -41,6 +41,7 @@ · 40 unmodified lines
4141 #include <linux/parser.h>
4242 #include <linux/fs_context.h>
4343 #include <linux/fs_parser.h>
44+#include <linux/watch_queue.h>
4445 #include "smack.h"
4546
4647 #define TRANS_TRUE "TRUE"
@@ -4284,7 +4285,7 @@ static int smack_key_permission(key_ref_t key_ref, · 4237 unmodified lines
42844285 if (tkp == NULL)
42854286 return -EACCES;
42864287
4287− if (smack_privileged_cred(CAP_MAC_OVERRIDE, cred))
4288+ if (smack_privileged(CAP_MAC_OVERRIDE))
42884289 return 0;
42894290
42904291 #ifdef CONFIG_AUDIT
@@ -4326,8 +4327,81 @@ static int smack_key_getsecurity(struct key *key, char **_buffer) · 35 unmodified lines
43264327 return length;
43274328 }
43284329
4330+
4331+#ifdef CONFIG_KEY_NOTIFICATIONS
4332+/**
4333+ * smack_watch_key - Smack access to watch a key for notifications.
4334+ * @key: The key to be watched
4335+ *
4336+ * Return 0 if the @watch->cred has permission to read from the key object and
4337+ * an error otherwise.
4338+ */
4339+static int smack_watch_key(struct key *key)
4340+{
4341+ struct smk_audit_info ad;
4342+ struct smack_known *tkp = smk_of_current();
4343+ int rc;
4344+
4345+ if (key == NULL)
4346+ return -EINVAL;
4347+ /*
4348+ * If the key hasn't been initialized give it access so that
4349+ * it may do so.
4350+ */
4351+ if (key->security == NULL)
4352+ return 0;
4353+ /*
4354+ * This should not occur
4355+ */
4356+ if (tkp == NULL)
4357+ return -EACCES;
4358+
4359+ if (smack_privileged_cred(CAP_MAC_OVERRIDE, current_cred()))
4360+ return 0;
4361+
4362+#ifdef CONFIG_AUDIT
4363+ smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_KEY);
4364+ ad.a.u.key_struct.key = key->serial;
4365+ ad.a.u.key_struct.key_desc = key->description;
4366+#endif
4367+ rc = smk_access(tkp, key->security, MAY_READ, &ad);
4368+ rc = smk_bu_note("key watch", tkp, key->security, MAY_READ, rc);
4369+ return rc;
4370+}
4371+#endif /* CONFIG_KEY_NOTIFICATIONS */
43294372 #endif /* CONFIG_KEYS */
43304373
4374+#ifdef CONFIG_WATCH_QUEUE
4375+/**
4376+ * smack_post_notification - Smack access to post a notification to a queue
4377+ * @w_cred: The credentials of the watcher.
4378+ * @cred: The credentials of the event source (may be NULL).
4379+ * @n: The notification message to be posted.
4380+ */
4381+static int smack_post_notification(const struct cred *w_cred,
4382+ const struct cred *cred,
4383+ struct watch_notification *n)
4384+{
4385+ struct smk_audit_info ad;
4386+ struct smack_known *subj, *obj;
4387+ int rc;
4388+
4389+ /* Always let maintenance notifications through. */
4390+ if (n->type == WATCH_TYPE_META)
4391+ return 0;
4392+
4393+ if (!cred)
4394+ return 0;
4395+ subj = smk_of_task(smack_cred(cred));
4396+ obj = smk_of_task(smack_cred(w_cred));
4397+
4398+ smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_NOTIFICATION);
4399+ rc = smk_access(subj, obj, MAY_WRITE, &ad);
4400+ rc = smk_bu_note("notification", subj, obj, MAY_WRITE, rc);
4401+ return rc;
4402+}
4403+#endif /* CONFIG_WATCH_QUEUE */
4404+
43314405 /*
43324406 * Smack Audit hooks
43334407 *
@@ -4716,8 +4790,15 @@ static struct security_hook_list smack_hooks[] __lsm_ro_after_init = { · 382 unmodified lines
47164790 LSM_HOOK_INIT(key_free, smack_key_free),
47174791 LSM_HOOK_INIT(key_permission, smack_key_permission),
47184792 LSM_HOOK_INIT(key_getsecurity, smack_key_getsecurity),
4793+#ifdef CONFIG_KEY_NOTIFICATIONS
4794+ LSM_HOOK_INIT(watch_key, smack_watch_key),
4795+#endif
47194796 #endif /* CONFIG_KEYS */
47204797
4798+#ifdef CONFIG_WATCH_QUEUE
4799+ LSM_HOOK_INIT(post_notification, smack_post_notification),
4800+#endif
4801+
47214802 /* Audit hooks */
47224803 #ifdef CONFIG_AUDIT
47234804 LSM_HOOK_INIT(audit_rule_init, smack_audit_rule_init),