History

[PATCH] selinux: add hooks for key subsystem

Introduce SELinux hooks to support the access key retention subsystem within the kernel. Incorporate new flask headers from a modified version of the SELinux reference policy, with support for the new security class representing retained keys. Extend the "key_alloc" security hook with a task parameter representing the intended ownership context for the key being allocated. Attach security information to root's default keyrings within the SELinux initialization routine. Has passed David's testsuite.

Michael LeMay committed 20 years ago

Commit d7200241 parent f893afb16 files · +155 −27Browse files

Showing the changes to security (12 of 16 files). Show all

Unified · Split

12 files
  1. security/dummy.c +1 −1
  2. security/keys/key.c +4 −4
  3. security/keys/keyring.c +3 −2
  4. security/keys/process_keys.c +8 −7
  5. security/keys/request_key.c +4 −2
  6. security/keys/request_key_auth.c +1 −1
  7. security/selinux/hooks.c +64 −0
  8. security/selinux/include/av_perm_to_string.h +6 −0
  9. security/selinux/include/av_permissions.h +8 −0
  10. security/selinux/include/class_to_string.h +1 −0
  11. security/selinux/include/flask.h +1 −0
  12. security/selinux/include/objsec.h +5 −0
security/dummy.c+1−1
@@ -860,7 +860,7 @@ static int dummy_setprocattr(struct task_struct *p, char *name, void *value, siz · 859 unmodified lines
860}860}
861 861
862#ifdef CONFIG_KEYS862#ifdef CONFIG_KEYS
863static inline int dummy_key_alloc(struct key *key)863static inline int dummy_key_alloc(struct key *key, struct task_struct *ctx)
864{864{
865 return 0;865 return 0;
866}866}
security/keys/key.c+4−4
@@ -247,8 +247,8 @@ static inline void key_alloc_serial(struct key *key) · 246 unmodified lines
247 * instantiate the key or discard it before returning247 * instantiate the key or discard it before returning
248 */248 */
249struct key *key_alloc(struct key_type *type, const char *desc,249struct key *key_alloc(struct key_type *type, const char *desc,
250 uid_t uid, gid_t gid, key_perm_t perm,250 uid_t uid, gid_t gid, struct task_struct *ctx,
251 int not_in_quota)251 key_perm_t perm, int not_in_quota)
252{252{
253 struct key_user *user = NULL;253 struct key_user *user = NULL;
254 struct key *key;254 struct key *key;
@@ -318,7 +318,7 @@ struct key *key_alloc(struct key_type *type, const char *desc, · 63 unmodified lines
318#endif318#endif
319 319
320 /* let the security module know about the key */320 /* let the security module know about the key */
321 ret = security_key_alloc(key);321 ret = security_key_alloc(key, ctx);
322 if (ret < 0)322 if (ret < 0)
323 goto security_error;323 goto security_error;
324 324
@@ -822,7 +822,7 @@ key_ref_t key_create_or_update(key_ref_t keyring_ref, · 497 unmodified lines
822 822
823 /* allocate a new key */823 /* allocate a new key */
824 key = key_alloc(ktype, description, current->fsuid, current->fsgid,824 key = key_alloc(ktype, description, current->fsuid, current->fsgid,
825 perm, not_in_quota);825 current, perm, not_in_quota);
826 if (IS_ERR(key)) {826 if (IS_ERR(key)) {
827 key_ref = ERR_PTR(PTR_ERR(key));827 key_ref = ERR_PTR(PTR_ERR(key));
828 goto error_3;828 goto error_3;
security/keys/keyring.c+3−2
@@ -240,13 +240,14 @@ static long keyring_read(const struct key *keyring, · 239 unmodified lines
240 * allocate a keyring and link into the destination keyring240 * allocate a keyring and link into the destination keyring
241 */241 */
242struct key *keyring_alloc(const char *description, uid_t uid, gid_t gid,242struct key *keyring_alloc(const char *description, uid_t uid, gid_t gid,
243 int not_in_quota, struct key *dest)243 struct task_struct *ctx, int not_in_quota,
244 struct key *dest)
244{245{
245 struct key *keyring;246 struct key *keyring;
246 int ret;247 int ret;
247 248
248 keyring = key_alloc(&key_type_keyring, description,249 keyring = key_alloc(&key_type_keyring, description,
249 uid, gid,250 uid, gid, ctx,
250 (KEY_POS_ALL & ~KEY_POS_SETATTR) | KEY_USR_ALL,251 (KEY_POS_ALL & ~KEY_POS_SETATTR) | KEY_USR_ALL,
251 not_in_quota);252 not_in_quota);
252 253
security/keys/process_keys.c+8−7
@@ -67,7 +67,8 @@ struct key root_session_keyring = { · 66 unmodified lines
67/*67/*
68 * allocate the keyrings to be associated with a UID68 * allocate the keyrings to be associated with a UID
69 */69 */
70int alloc_uid_keyring(struct user_struct *user)70int alloc_uid_keyring(struct user_struct *user,
71 struct task_struct *ctx)
71{72{
72 struct key *uid_keyring, *session_keyring;73 struct key *uid_keyring, *session_keyring;
73 char buf[20];74 char buf[20];
@@ -76,7 +77,7 @@ int alloc_uid_keyring(struct user_struct *user) · 2 unmodified lines
76 /* concoct a default session keyring */77 /* concoct a default session keyring */
77 sprintf(buf, "_uid_ses.%u", user->uid);78 sprintf(buf, "_uid_ses.%u", user->uid);
78 79
79 session_keyring = keyring_alloc(buf, user->uid, (gid_t) -1, 0, NULL);80 session_keyring = keyring_alloc(buf, user->uid, (gid_t) -1, ctx, 0, NULL);
80 if (IS_ERR(session_keyring)) {81 if (IS_ERR(session_keyring)) {
81 ret = PTR_ERR(session_keyring);82 ret = PTR_ERR(session_keyring);
82 goto error;83 goto error;
@@ -86,7 +87,7 @@ int alloc_uid_keyring(struct user_struct *user) · 3 unmodified lines
86 * keyring */87 * keyring */
87 sprintf(buf, "_uid.%u", user->uid);88 sprintf(buf, "_uid.%u", user->uid);
88 89
89 uid_keyring = keyring_alloc(buf, user->uid, (gid_t) -1, 0,90 uid_keyring = keyring_alloc(buf, user->uid, (gid_t) -1, ctx, 0,
90 session_keyring);91 session_keyring);
91 if (IS_ERR(uid_keyring)) {92 if (IS_ERR(uid_keyring)) {
92 key_put(session_keyring);93 key_put(session_keyring);
@@ -143,7 +144,7 @@ int install_thread_keyring(struct task_struct *tsk) · 50 unmodified lines
143 144
144 sprintf(buf, "_tid.%u", tsk->pid);145 sprintf(buf, "_tid.%u", tsk->pid);
145 146
146 keyring = keyring_alloc(buf, tsk->uid, tsk->gid, 1, NULL);147 keyring = keyring_alloc(buf, tsk->uid, tsk->gid, tsk, 1, NULL);
147 if (IS_ERR(keyring)) {148 if (IS_ERR(keyring)) {
148 ret = PTR_ERR(keyring);149 ret = PTR_ERR(keyring);
149 goto error;150 goto error;
@@ -177,7 +178,7 @@ int install_process_keyring(struct task_struct *tsk) · 27 unmodified lines
177 if (!tsk->signal->process_keyring) {178 if (!tsk->signal->process_keyring) {
178 sprintf(buf, "_pid.%u", tsk->tgid);179 sprintf(buf, "_pid.%u", tsk->tgid);
179 180
180 keyring = keyring_alloc(buf, tsk->uid, tsk->gid, 1, NULL);181 keyring = keyring_alloc(buf, tsk->uid, tsk->gid, tsk, 1, NULL);
181 if (IS_ERR(keyring)) {182 if (IS_ERR(keyring)) {
182 ret = PTR_ERR(keyring);183 ret = PTR_ERR(keyring);
183 goto error;184 goto error;
@@ -217,7 +218,7 @@ static int install_session_keyring(struct task_struct *tsk, · 33 unmodified lines
217 if (!keyring) {218 if (!keyring) {
218 sprintf(buf, "_ses.%u", tsk->tgid);219 sprintf(buf, "_ses.%u", tsk->tgid);
219 220
220 keyring = keyring_alloc(buf, tsk->uid, tsk->gid, 1, NULL);221 keyring = keyring_alloc(buf, tsk->uid, tsk->gid, tsk, 1, NULL);
221 if (IS_ERR(keyring))222 if (IS_ERR(keyring))
222 return PTR_ERR(keyring);223 return PTR_ERR(keyring);
223 }224 }
@@ -717,7 +718,7 @@ long join_session_keyring(const char *name) · 493 unmodified lines
717 keyring = find_keyring_by_name(name, 0);718 keyring = find_keyring_by_name(name, 0);
718 if (PTR_ERR(keyring) == -ENOKEY) {719 if (PTR_ERR(keyring) == -ENOKEY) {
719 /* not found - try and create a new one */720 /* not found - try and create a new one */
720 keyring = keyring_alloc(name, tsk->uid, tsk->gid, 0, NULL);721 keyring = keyring_alloc(name, tsk->uid, tsk->gid, tsk, 0, NULL);
721 if (IS_ERR(keyring)) {722 if (IS_ERR(keyring)) {
722 ret = PTR_ERR(keyring);723 ret = PTR_ERR(keyring);
723 goto error2;724 goto error2;
security/keys/request_key.c+4−2
@@ -48,7 +48,8 @@ static int call_sbin_request_key(struct key *key, · 47 unmodified lines
48 /* allocate a new session keyring */48 /* allocate a new session keyring */
49 sprintf(desc, "_req.%u", key->serial);49 sprintf(desc, "_req.%u", key->serial);
50 50
51 keyring = keyring_alloc(desc, current->fsuid, current->fsgid, 1, NULL);51 keyring = keyring_alloc(desc, current->fsuid, current->fsgid,
52 current, 1, NULL);
52 if (IS_ERR(keyring)) {53 if (IS_ERR(keyring)) {
53 ret = PTR_ERR(keyring);54 ret = PTR_ERR(keyring);
54 goto error_alloc;55 goto error_alloc;
@@ -137,7 +138,8 @@ static struct key *__request_key_construction(struct key_type *type, · 82 unmodified lines
137 138
138 /* create a key and add it to the queue */139 /* create a key and add it to the queue */
139 key = key_alloc(type, description,140 key = key_alloc(type, description,
140 current->fsuid, current->fsgid, KEY_POS_ALL, 0);141 current->fsuid, current->fsgid,
142 current, KEY_POS_ALL, 0);
141 if (IS_ERR(key))143 if (IS_ERR(key))
142 goto alloc_failed;144 goto alloc_failed;
143 145
security/keys/request_key_auth.c+1−1
@@ -148,7 +148,7 @@ struct key *request_key_auth_new(struct key *target, const char *callout_info) · 147 unmodified lines
148 sprintf(desc, "%x", target->serial);148 sprintf(desc, "%x", target->serial);
149 149
150 authkey = key_alloc(&key_type_request_key_auth, desc,150 authkey = key_alloc(&key_type_request_key_auth, desc,
151 current->fsuid, current->fsgid,151 current->fsuid, current->fsgid, current,
152 KEY_POS_VIEW | KEY_POS_READ | KEY_POS_SEARCH |152 KEY_POS_VIEW | KEY_POS_READ | KEY_POS_SEARCH |
153 KEY_USR_VIEW, 1);153 KEY_USR_VIEW, 1);
154 if (IS_ERR(authkey)) {154 if (IS_ERR(authkey)) {
security/selinux/hooks.c+64−0
@@ -4252,6 +4252,57 @@ static int selinux_setprocattr(struct task_struct *p, · 4251 unmodified lines
4252 return size;4252 return size;
4253}4253}
4254 4254
4255#ifdef CONFIG_KEYS
4256
4257static int selinux_key_alloc(struct key *k, struct task_struct *tsk)
4258{
4259 struct task_security_struct *tsec = tsk->security;
4260 struct key_security_struct *ksec;
4261
4262 ksec = kzalloc(sizeof(struct key_security_struct), GFP_KERNEL);
4263 if (!ksec)
4264 return -ENOMEM;
4265
4266 ksec->obj = k;
4267 ksec->sid = tsec->sid;
4268 k->security = ksec;
4269
4270 return 0;
4271}
4272
4273static void selinux_key_free(struct key *k)
4274{
4275 struct key_security_struct *ksec = k->security;
4276
4277 k->security = NULL;
4278 kfree(ksec);
4279}
4280
4281static int selinux_key_permission(key_ref_t key_ref,
4282 struct task_struct *ctx,
4283 key_perm_t perm)
4284{
4285 struct key *key;
4286 struct task_security_struct *tsec;
4287 struct key_security_struct *ksec;
4288
4289 key = key_ref_to_ptr(key_ref);
4290
4291 tsec = ctx->security;
4292 ksec = key->security;
4293
4294 /* if no specific permissions are requested, we skip the
4295 permission check. No serious, additional covert channels
4296 appear to be created. */
4297 if (perm == 0)
4298 return 0;
4299
4300 return avc_has_perm(tsec->sid, ksec->sid,
4301 SECCLASS_KEY, perm, NULL);
4302}
4303
4304#endif
4305
4255static struct security_operations selinux_ops = {4306static struct security_operations selinux_ops = {
4256 .ptrace = selinux_ptrace,4307 .ptrace = selinux_ptrace,
4257 .capget = selinux_capget,4308 .capget = selinux_capget,
@@ -4406,6 +4457,12 @@ static struct security_operations selinux_ops = { · 148 unmodified lines
4406 .xfrm_state_delete_security = selinux_xfrm_state_delete,4457 .xfrm_state_delete_security = selinux_xfrm_state_delete,
4407 .xfrm_policy_lookup = selinux_xfrm_policy_lookup,4458 .xfrm_policy_lookup = selinux_xfrm_policy_lookup,
4408#endif4459#endif
4460
4461#ifdef CONFIG_KEYS
4462 .key_alloc = selinux_key_alloc,
4463 .key_free = selinux_key_free,
4464 .key_permission = selinux_key_permission,
4465#endif
4409};4466};
4410 4467
4411static __init int selinux_init(void)4468static __init int selinux_init(void)
@@ -4441,6 +4498,13 @@ static __init int selinux_init(void) · 29 unmodified lines
4441 } else {4498 } else {
4442 printk(KERN_INFO "SELinux: Starting in permissive mode\n");4499 printk(KERN_INFO "SELinux: Starting in permissive mode\n");
4443 }4500 }
4501
4502#ifdef CONFIG_KEYS
4503 /* Add security information to initial keyrings */
4504 security_key_alloc(&root_user_keyring, current);
4505 security_key_alloc(&root_session_keyring, current);
4506#endif
4507
4444 return 0;4508 return 0;
4445}4509}
4446 4510
security/selinux/include/av_perm_to_string.h+6−0
@@ -242,3 +242,9 @@ · 241 unmodified lines
242 S_(SECCLASS_PACKET, PACKET__SEND, "send")242 S_(SECCLASS_PACKET, PACKET__SEND, "send")
243 S_(SECCLASS_PACKET, PACKET__RECV, "recv")243 S_(SECCLASS_PACKET, PACKET__RECV, "recv")
244 S_(SECCLASS_PACKET, PACKET__RELABELTO, "relabelto")244 S_(SECCLASS_PACKET, PACKET__RELABELTO, "relabelto")
245 S_(SECCLASS_KEY, KEY__VIEW, "view")
246 S_(SECCLASS_KEY, KEY__READ, "read")
247 S_(SECCLASS_KEY, KEY__WRITE, "write")
248 S_(SECCLASS_KEY, KEY__SEARCH, "search")
249 S_(SECCLASS_KEY, KEY__LINK, "link")
250 S_(SECCLASS_KEY, KEY__SETATTR, "setattr")
security/selinux/include/av_permissions.h+8−0
@@ -959,3 +959,11 @@ · 958 unmodified lines
959#define PACKET__SEND 0x00000001UL959#define PACKET__SEND 0x00000001UL
960#define PACKET__RECV 0x00000002UL960#define PACKET__RECV 0x00000002UL
961#define PACKET__RELABELTO 0x00000004UL961#define PACKET__RELABELTO 0x00000004UL
962
963#define KEY__VIEW 0x00000001UL
964#define KEY__READ 0x00000002UL
965#define KEY__WRITE 0x00000004UL
966#define KEY__SEARCH 0x00000008UL
967#define KEY__LINK 0x00000010UL
968#define KEY__SETATTR 0x00000020UL
969
security/selinux/include/class_to_string.h+1−0
@@ -60,3 +60,4 @@ · 59 unmodified lines
60 S_("netlink_kobject_uevent_socket")60 S_("netlink_kobject_uevent_socket")
61 S_("appletalk_socket")61 S_("appletalk_socket")
62 S_("packet")62 S_("packet")
63 S_("key")
security/selinux/include/flask.h+1−0
@@ -62,6 +62,7 @@ · 61 unmodified lines
62#define SECCLASS_NETLINK_KOBJECT_UEVENT_SOCKET 5562#define SECCLASS_NETLINK_KOBJECT_UEVENT_SOCKET 55
63#define SECCLASS_APPLETALK_SOCKET 5663#define SECCLASS_APPLETALK_SOCKET 56
64#define SECCLASS_PACKET 5764#define SECCLASS_PACKET 57
65#define SECCLASS_KEY 58
65 66
66/*67/*
67 * Security identifier indices for initial entities68 * Security identifier indices for initial entities
security/selinux/include/objsec.h+5−0
@@ -99,6 +99,11 @@ struct sk_security_struct { · 98 unmodified lines
99 u32 peer_sid; /* SID of peer */99 u32 peer_sid; /* SID of peer */
100};100};
101 101
102struct key_security_struct {
103 struct key *obj; /* back pointer */
104 u32 sid; /* SID of key */
105};
106
102extern unsigned int selinux_checkreqprot;107extern unsigned int selinux_checkreqprot;
103 108
104#endif /* _SELINUX_OBJSEC_H_ */109#endif /* _SELINUX_OBJSEC_H_ */