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
75#define LSM_AUDIT_DATA_IBPKEY 1375#define LSM_AUDIT_DATA_IBPKEY 13
76#define LSM_AUDIT_DATA_IBENDPORT 1476#define LSM_AUDIT_DATA_IBENDPORT 14
77#define LSM_AUDIT_DATA_LOCKDOWN 1577#define LSM_AUDIT_DATA_LOCKDOWN 15
78#define LSM_AUDIT_DATA_NOTIFICATION 16
78 union {79 union {
79 struct path path;80 struct path path;
80 struct dentry *dentry;81 struct dentry *dentry;
security/smack/smack_lsm.c+82−1
@@ -41,6 +41,7 @@ · 40 unmodified lines
41#include <linux/parser.h>41#include <linux/parser.h>
42#include <linux/fs_context.h>42#include <linux/fs_context.h>
43#include <linux/fs_parser.h>43#include <linux/fs_parser.h>
44#include <linux/watch_queue.h>
44#include "smack.h"45#include "smack.h"
45 46
46#define TRANS_TRUE "TRUE"47#define TRANS_TRUE "TRUE"
@@ -4284,7 +4285,7 @@ static int smack_key_permission(key_ref_t key_ref, · 4237 unmodified lines
4284 if (tkp == NULL)4285 if (tkp == NULL)
4285 return -EACCES;4286 return -EACCES;
4286 4287
4287 if (smack_privileged_cred(CAP_MAC_OVERRIDE, cred))4288 if (smack_privileged(CAP_MAC_OVERRIDE))
4288 return 0;4289 return 0;
4289 4290
4290#ifdef CONFIG_AUDIT4291#ifdef CONFIG_AUDIT
@@ -4326,8 +4327,81 @@ static int smack_key_getsecurity(struct key *key, char **_buffer) · 35 unmodified lines
4326 return length;4327 return length;
4327}4328}
4328 4329
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 */
4339static 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 */
4329#endif /* CONFIG_KEYS */4372#endif /* CONFIG_KEYS */
4330 4373
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 */
4381static 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
4331/*4405/*
4332 * Smack Audit hooks4406 * Smack Audit hooks
4333 *4407 *
@@ -4716,8 +4790,15 @@ static struct security_hook_list smack_hooks[] __lsm_ro_after_init = { · 382 unmodified lines
4716 LSM_HOOK_INIT(key_free, smack_key_free),4790 LSM_HOOK_INIT(key_free, smack_key_free),
4717 LSM_HOOK_INIT(key_permission, smack_key_permission),4791 LSM_HOOK_INIT(key_permission, smack_key_permission),
4718 LSM_HOOK_INIT(key_getsecurity, smack_key_getsecurity),4792 LSM_HOOK_INIT(key_getsecurity, smack_key_getsecurity),
4793#ifdef CONFIG_KEY_NOTIFICATIONS
4794 LSM_HOOK_INIT(watch_key, smack_watch_key),
4795#endif
4719#endif /* CONFIG_KEYS */4796#endif /* CONFIG_KEYS */
4720 4797
4798#ifdef CONFIG_WATCH_QUEUE
4799 LSM_HOOK_INIT(post_notification, smack_post_notification),
4800#endif
4801
4721 /* Audit hooks */4802 /* Audit hooks */
4722#ifdef CONFIG_AUDIT4803#ifdef CONFIG_AUDIT
4723 LSM_HOOK_INIT(audit_rule_init, smack_audit_rule_init),4804 LSM_HOOK_INIT(audit_rule_init, smack_audit_rule_init),