|
41 | 41 | #include <linux/parser.h>
|
42 | 42 | #include <linux/fs_context.h>
|
43 | 43 | #include <linux/fs_parser.h>
|
| 44 | +#include <linux/watch_queue.h> |
44 | 45 | #include "smack.h"
|
45 | 46 |
|
46 | 47 | #define TRANS_TRUE "TRUE"
|
@@ -4284,7 +4285,7 @@ static int smack_key_permission(key_ref_t key_ref,
|
4284 | 4285 | if (tkp == NULL)
|
4285 | 4286 | return -EACCES;
|
4286 | 4287 |
|
4287 |
| - if (smack_privileged_cred(CAP_MAC_OVERRIDE, cred)) |
| 4288 | + if (smack_privileged(CAP_MAC_OVERRIDE)) |
4288 | 4289 | return 0;
|
4289 | 4290 |
|
4290 | 4291 | #ifdef CONFIG_AUDIT
|
@@ -4326,8 +4327,81 @@ static int smack_key_getsecurity(struct key *key, char **_buffer)
|
4326 | 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 | + */ |
| 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 */ |
4329 | 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 | + */ |
| 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 | + |
4331 | 4405 | /*
|
4332 | 4406 | * Smack Audit hooks
|
4333 | 4407 | *
|
@@ -4716,8 +4790,15 @@ static struct security_hook_list smack_hooks[] __lsm_ro_after_init = {
|
4716 | 4790 | LSM_HOOK_INIT(key_free, smack_key_free),
|
4717 | 4791 | LSM_HOOK_INIT(key_permission, smack_key_permission),
|
4718 | 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 | 4796 | #endif /* CONFIG_KEYS */
|
4720 | 4797 |
|
| 4798 | +#ifdef CONFIG_WATCH_QUEUE |
| 4799 | + LSM_HOOK_INIT(post_notification, smack_post_notification), |
| 4800 | +#endif |
| 4801 | + |
4721 | 4802 | /* Audit hooks */
|
4722 | 4803 | #ifdef CONFIG_AUDIT
|
4723 | 4804 | LSM_HOOK_INIT(audit_rule_init, smack_audit_rule_init),
|
|
0 commit comments