Skip to content

Commit a8478a6

Browse files
committed
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. Signed-off-by: David Howells <[email protected]> Acked-by: Casey Schaufler <[email protected]>
1 parent 3e412cc commit a8478a6

File tree

2 files changed

+83
-1
lines changed

2 files changed

+83
-1
lines changed

include/linux/lsm_audit.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ struct common_audit_data {
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

Lines changed: 82 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
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,
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)
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 = {
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),

0 commit comments

Comments
 (0)