History

watch_queue: Add a key/keyring notification facility

Add a key/keyring change notification facility whereby notifications about changes in key and keyring content and attributes can be received. Firstly, an event queue needs to be created: pipe2(fds, O_NOTIFICATION_PIPE); ioctl(fds[1], IOC_WATCH_QUEUE_SET_SIZE, 256); then a notification can be set up to report notifications via that queue: struct watch_notification_filter filter = { .nr_filters = 1, .filters = { [0] = { .type = WATCH_TYPE_KEY_NOTIFY, .subtype_filter[0] = UINT_MAX, }, }, }; ioctl(fds[1], IOC_WATCH_QUEUE_SET_FILTER, &filter); keyctl_watch_key(KEY_SPEC_SESSION_KEYRING, fds[1], 0x01); After that, records will be placed into the queue when events occur in which keys are changed in some way. Records are of the following format: struct key_notification { struct watch_notification watch; __u32 key_id; __u32 aux; } *n; Where: n->watch.type will be WATCH_TYPE_KEY_NOTIFY. n->watch.subtype will indicate the type of event, such as NOTIFY_KEY_REVOKED. n->watch.info & WATCH_INFO_LENGTH will indicate the length of the record. n->watch.info & WATCH_INFO_ID will be the second argument to keyctl_watch_key(), shifted. n->key will be the ID of the affected key. n->aux will hold subtype-dependent information, such as the key being linked into the keyring specified by n->key in the case of NOTIFY_KEY_LINKED. Note that it is permissible for event records to be of variable length - or, at least, the length may be dependent on the subtype. Note also that the queue can be shared between multiple notifications of various types.

David Howells committed 6 years ago

Commit f7e47671 parent 998f50412 files · +270 −28Browse files

Unified · Split

12 files
  1. Documentation/security/keys/core.rst +57 −0
  2. include/linux/key.h +3 −0
  3. include/uapi/linux/keyctl.h +2 −0
  4. include/uapi/linux/watch_queue.h +27 −1
  5. security/keys/Kconfig +9 −0
  6. security/keys/compat.c +3 −0
  7. security/keys/gc.c +5 −0
  8. security/keys/internal.h +29 −1
  9. security/keys/key.c +24 −14
  10. security/keys/keyctl.c +96 −3
  11. security/keys/keyring.c +13 −7
  12. security/keys/request_key.c +2 −2
Documentation/security/keys/core.rst+57−0
@@ -1026,6 +1026,63 @@ The keyctl syscall functions are: · 1025 unmodified lines
1026 written into the output buffer. Verification returns 0 on success.1026 written into the output buffer. Verification returns 0 on success.
1027 1027
1028 1028
1029 * Watch a key or keyring for changes::
1030
1031 long keyctl(KEYCTL_WATCH_KEY, key_serial_t key, int queue_fd,
1032 const struct watch_notification_filter *filter);
1033
1034 This will set or remove a watch for changes on the specified key or
1035 keyring.
1036
1037 "key" is the ID of the key to be watched.
1038
1039 "queue_fd" is a file descriptor referring to an open "/dev/watch_queue"
1040 which manages the buffer into which notifications will be delivered.
1041
1042 "filter" is either NULL to remove a watch or a filter specification to
1043 indicate what events are required from the key.
1044
1045 See Documentation/watch_queue.rst for more information.
1046
1047 Note that only one watch may be emplaced for any particular { key,
1048 queue_fd } combination.
1049
1050 Notification records look like::
1051
1052 struct key_notification {
1053 struct watch_notification watch;
1054 __u32 key_id;
1055 __u32 aux;
1056 };
1057
1058 In this, watch::type will be "WATCH_TYPE_KEY_NOTIFY" and subtype will be
1059 one of::
1060
1061 NOTIFY_KEY_INSTANTIATED
1062 NOTIFY_KEY_UPDATED
1063 NOTIFY_KEY_LINKED
1064 NOTIFY_KEY_UNLINKED
1065 NOTIFY_KEY_CLEARED
1066 NOTIFY_KEY_REVOKED
1067 NOTIFY_KEY_INVALIDATED
1068 NOTIFY_KEY_SETATTR
1069
1070 Where these indicate a key being instantiated/rejected, updated, a link
1071 being made in a keyring, a link being removed from a keyring, a keyring
1072 being cleared, a key being revoked, a key being invalidated or a key
1073 having one of its attributes changed (user, group, perm, timeout,
1074 restriction).
1075
1076 If a watched key is deleted, a basic watch_notification will be issued
1077 with "type" set to WATCH_TYPE_META and "subtype" set to
1078 watch_meta_removal_notification. The watchpoint ID will be set in the
1079 "info" field.
1080
1081 This needs to be configured by enabling:
1082
1083 "Provide key/keyring change notifications" (KEY_NOTIFICATIONS)
1084
1085
1029Kernel Services1086Kernel Services
1030===============1087===============
1031 1088
include/linux/key.h+3−0
@@ -176,6 +176,9 @@ struct key { · 175 unmodified lines
176 struct list_head graveyard_link;176 struct list_head graveyard_link;
177 struct rb_node serial_node;177 struct rb_node serial_node;
178 };178 };
179#ifdef CONFIG_KEY_NOTIFICATIONS
180 struct watch_list *watchers; /* Entities watching this key for changes */
181#endif
179 struct rw_semaphore sem; /* change vs change sem */182 struct rw_semaphore sem; /* change vs change sem */
180 struct key_user *user; /* owner of this key */183 struct key_user *user; /* owner of this key */
181 void *security; /* security data for this key */184 void *security; /* security data for this key */
include/uapi/linux/keyctl.h+2−0
@@ -69,6 +69,7 @@ · 68 unmodified lines
69#define KEYCTL_RESTRICT_KEYRING 29 /* Restrict keys allowed to link to a keyring */69#define KEYCTL_RESTRICT_KEYRING 29 /* Restrict keys allowed to link to a keyring */
70#define KEYCTL_MOVE 30 /* Move keys between keyrings */70#define KEYCTL_MOVE 30 /* Move keys between keyrings */
71#define KEYCTL_CAPABILITIES 31 /* Find capabilities of keyrings subsystem */71#define KEYCTL_CAPABILITIES 31 /* Find capabilities of keyrings subsystem */
72#define KEYCTL_WATCH_KEY 32 /* Watch a key or ring of keys for changes */
72 73
73/* keyctl structures */74/* keyctl structures */
74struct keyctl_dh_params {75struct keyctl_dh_params {
@@ -130,5 +131,6 @@ struct keyctl_pkey_params { · 55 unmodified lines
130#define KEYCTL_CAPS0_MOVE 0x80 /* KEYCTL_MOVE supported */131#define KEYCTL_CAPS0_MOVE 0x80 /* KEYCTL_MOVE supported */
131#define KEYCTL_CAPS1_NS_KEYRING_NAME 0x01 /* Keyring names are per-user_namespace */132#define KEYCTL_CAPS1_NS_KEYRING_NAME 0x01 /* Keyring names are per-user_namespace */
132#define KEYCTL_CAPS1_NS_KEY_TAG 0x02 /* Key indexing can include a namespace tag */133#define KEYCTL_CAPS1_NS_KEY_TAG 0x02 /* Key indexing can include a namespace tag */
134#define KEYCTL_CAPS1_NOTIFICATIONS 0x04 /* Keys generate watchable notifications */
133 135
134#endif /* _LINUX_KEYCTL_H */136#endif /* _LINUX_KEYCTL_H */
include/uapi/linux/watch_queue.h+27−1
@@ -13,7 +13,8 @@ · 12 unmodified lines
13 13
14enum watch_notification_type {14enum watch_notification_type {
15 WATCH_TYPE_META = 0, /* Special record */15 WATCH_TYPE_META = 0, /* Special record */
16 WATCH_TYPE__NR = 116 WATCH_TYPE_KEY_NOTIFY = 1, /* Key change event notification */
17 WATCH_TYPE__NR = 2
17};18};
18 19
19enum watch_meta_notification_subtype {20enum watch_meta_notification_subtype {
@@ -75,4 +76,29 @@ struct watch_notification_removal { · 55 unmodified lines
75 __u64 id; /* Type-dependent identifier */76 __u64 id; /* Type-dependent identifier */
76};77};
77 78
79/*
80 * Type of key/keyring change notification.
81 */
82enum key_notification_subtype {
83 NOTIFY_KEY_INSTANTIATED = 0, /* Key was instantiated (aux is error code) */
84 NOTIFY_KEY_UPDATED = 1, /* Key was updated */
85 NOTIFY_KEY_LINKED = 2, /* Key (aux) was added to watched keyring */
86 NOTIFY_KEY_UNLINKED = 3, /* Key (aux) was removed from watched keyring */
87 NOTIFY_KEY_CLEARED = 4, /* Keyring was cleared */
88 NOTIFY_KEY_REVOKED = 5, /* Key was revoked */
89 NOTIFY_KEY_INVALIDATED = 6, /* Key was invalidated */
90 NOTIFY_KEY_SETATTR = 7, /* Key's attributes got changed */
91};
92
93/*
94 * Key/keyring notification record.
95 * - watch.type = WATCH_TYPE_KEY_NOTIFY
96 * - watch.subtype = enum key_notification_type
97 */
98struct key_notification {
99 struct watch_notification watch;
100 __u32 key_id; /* The key/keyring affected */
101 __u32 aux; /* Per-type auxiliary data */
102};
103
78#endif /* _UAPI_LINUX_WATCH_QUEUE_H */104#endif /* _UAPI_LINUX_WATCH_QUEUE_H */
security/keys/Kconfig+9−0
@@ -116,3 +116,12 @@ config KEY_DH_OPERATIONS · 115 unmodified lines
116 in the kernel.116 in the kernel.
117 117
118 If you are unsure as to whether this is required, answer N.118 If you are unsure as to whether this is required, answer N.
119
120config KEY_NOTIFICATIONS
121 bool "Provide key/keyring change notifications"
122 depends on KEYS && WATCH_QUEUE
123 help
124 This option provides support for getting change notifications on keys
125 and keyrings on which the caller has View permission. This makes use
126 of the /dev/watch_queue misc device to handle the notification
127 buffer and provides KEYCTL_WATCH_KEY to enable/disable watches.
security/keys/compat.c+3−0
@@ -156,6 +156,9 @@ COMPAT_SYSCALL_DEFINE5(keyctl, u32, option, · 155 unmodified lines
156 case KEYCTL_CAPABILITIES:156 case KEYCTL_CAPABILITIES:
157 return keyctl_capabilities(compat_ptr(arg2), arg3);157 return keyctl_capabilities(compat_ptr(arg2), arg3);
158 158
159 case KEYCTL_WATCH_KEY:
160 return keyctl_watch_key(arg2, arg3, arg4);
161
159 default:162 default:
160 return -EOPNOTSUPP;163 return -EOPNOTSUPP;
161 }164 }
security/keys/gc.c+5−0
@@ -131,6 +131,11 @@ static noinline void key_gc_unused_keys(struct list_head *keys) · 130 unmodified lines
131 kdebug("- %u", key->serial);131 kdebug("- %u", key->serial);
132 key_check(key);132 key_check(key);
133 133
134#ifdef CONFIG_KEY_NOTIFICATIONS
135 remove_watch_list(key->watchers, key->serial);
136 key->watchers = NULL;
137#endif
138
134 /* Throw away the key data if the key is instantiated */139 /* Throw away the key data if the key is instantiated */
135 if (state == KEY_IS_POSITIVE && key->type->destroy)140 if (state == KEY_IS_POSITIVE && key->type->destroy)
136 key->type->destroy(key);141 key->type->destroy(key);
security/keys/internal.h+29−1
@@ -15,6 +15,7 @@ · 14 unmodified lines
15#include <linux/task_work.h>15#include <linux/task_work.h>
16#include <linux/keyctl.h>16#include <linux/keyctl.h>
17#include <linux/refcount.h>17#include <linux/refcount.h>
18#include <linux/watch_queue.h>
18#include <linux/compat.h>19#include <linux/compat.h>
19#include <linux/mm.h>20#include <linux/mm.h>
20#include <linux/vmalloc.h>21#include <linux/vmalloc.h>
@@ -99,7 +100,8 @@ extern int __key_link_begin(struct key *keyring, · 78 unmodified lines
99 const struct keyring_index_key *index_key,100 const struct keyring_index_key *index_key,
100 struct assoc_array_edit **_edit);101 struct assoc_array_edit **_edit);
101extern int __key_link_check_live_key(struct key *keyring, struct key *key);102extern int __key_link_check_live_key(struct key *keyring, struct key *key);
102extern void __key_link(struct key *key, struct assoc_array_edit **_edit);103extern void __key_link(struct key *keyring, struct key *key,
104 struct assoc_array_edit **_edit);
103extern void __key_link_end(struct key *keyring,105extern void __key_link_end(struct key *keyring,
104 const struct keyring_index_key *index_key,106 const struct keyring_index_key *index_key,
105 struct assoc_array_edit *edit);107 struct assoc_array_edit *edit);
@@ -183,6 +185,23 @@ extern int key_task_permission(const key_ref_t key_ref, · 77 unmodified lines
183 const struct cred *cred,185 const struct cred *cred,
184 key_perm_t perm);186 key_perm_t perm);
185 187
188static inline void notify_key(struct key *key,
189 enum key_notification_subtype subtype, u32 aux)
190{
191#ifdef CONFIG_KEY_NOTIFICATIONS
192 struct key_notification n = {
193 .watch.type = WATCH_TYPE_KEY_NOTIFY,
194 .watch.subtype = subtype,
195 .watch.info = watch_sizeof(n),
196 .key_id = key_serial(key),
197 .aux = aux,
198 };
199
200 post_watch_notification(key->watchers, &n.watch, current_cred(),
201 n.key_id);
202#endif
203}
204
186/*205/*
187 * Check to see whether permission is granted to use a key in the desired way.206 * Check to see whether permission is granted to use a key in the desired way.
188 */207 */
@@ -333,6 +352,15 @@ static inline long keyctl_pkey_e_d_s(int op, · 144 unmodified lines
333 352
334extern long keyctl_capabilities(unsigned char __user *_buffer, size_t buflen);353extern long keyctl_capabilities(unsigned char __user *_buffer, size_t buflen);
335 354
355#ifdef CONFIG_KEY_NOTIFICATIONS
356extern long keyctl_watch_key(key_serial_t, int, int);
357#else
358static inline long keyctl_watch_key(key_serial_t key_id, int watch_fd, int watch_id)
359{
360 return -EOPNOTSUPP;
361}
362#endif
363
336/*364/*
337 * Debugging key validation365 * Debugging key validation
338 */366 */
security/keys/key.c+24−14
@@ -444,6 +444,7 @@ static int __key_instantiate_and_link(struct key *key, · 443 unmodified lines
444 /* mark the key as being instantiated */444 /* mark the key as being instantiated */
445 atomic_inc(&key->user->nikeys);445 atomic_inc(&key->user->nikeys);
446 mark_key_instantiated(key, 0);446 mark_key_instantiated(key, 0);
447 notify_key(key, NOTIFY_KEY_INSTANTIATED, 0);
447 448
448 if (test_and_clear_bit(KEY_FLAG_USER_CONSTRUCT, &key->flags))449 if (test_and_clear_bit(KEY_FLAG_USER_CONSTRUCT, &key->flags))
449 awaken = 1;450 awaken = 1;
@@ -453,7 +454,7 @@ static int __key_instantiate_and_link(struct key *key, · 3 unmodified lines
453 if (test_bit(KEY_FLAG_KEEP, &keyring->flags))454 if (test_bit(KEY_FLAG_KEEP, &keyring->flags))
454 set_bit(KEY_FLAG_KEEP, &key->flags);455 set_bit(KEY_FLAG_KEEP, &key->flags);
455 456
456 __key_link(key, _edit);457 __key_link(keyring, key, _edit);
457 }458 }
458 459
459 /* disable the authorisation key */460 /* disable the authorisation key */
@@ -601,6 +602,7 @@ int key_reject_and_link(struct key *key, · 141 unmodified lines
601 /* mark the key as being negatively instantiated */602 /* mark the key as being negatively instantiated */
602 atomic_inc(&key->user->nikeys);603 atomic_inc(&key->user->nikeys);
603 mark_key_instantiated(key, -error);604 mark_key_instantiated(key, -error);
605 notify_key(key, NOTIFY_KEY_INSTANTIATED, -error);
604 key->expiry = ktime_get_real_seconds() + timeout;606 key->expiry = ktime_get_real_seconds() + timeout;
605 key_schedule_gc(key->expiry + key_gc_delay);607 key_schedule_gc(key->expiry + key_gc_delay);
606 608
@@ -611,7 +613,7 @@ int key_reject_and_link(struct key *key, · 4 unmodified lines
611 613
612 /* and link it into the destination keyring */614 /* and link it into the destination keyring */
613 if (keyring && link_ret == 0)615 if (keyring && link_ret == 0)
614 __key_link(key, &edit);616 __key_link(keyring, key, &edit);
615 617
616 /* disable the authorisation key */618 /* disable the authorisation key */
617 if (authkey)619 if (authkey)
@@ -764,9 +766,11 @@ static inline key_ref_t __key_update(key_ref_t key_ref, · 146 unmodified lines
764 down_write(&key->sem);766 down_write(&key->sem);
765 767
766 ret = key->type->update(key, prep);768 ret = key->type->update(key, prep);
767 if (ret == 0)769 if (ret == 0) {
768 /* Updating a negative key positively instantiates it */770 /* Updating a negative key positively instantiates it */
769 mark_key_instantiated(key, 0);771 mark_key_instantiated(key, 0);
772 notify_key(key, NOTIFY_KEY_UPDATED, 0);
773 }
770 774
771 up_write(&key->sem);775 up_write(&key->sem);
772 776
@@ -1023,9 +1027,11 @@ int key_update(key_ref_t key_ref, const void *payload, size_t plen) · 250 unmodified lines
1023 down_write(&key->sem);1027 down_write(&key->sem);
1024 1028
1025 ret = key->type->update(key, &prep);1029 ret = key->type->update(key, &prep);
1026 if (ret == 0)1030 if (ret == 0) {
1027 /* Updating a negative key positively instantiates it */1031 /* Updating a negative key positively instantiates it */
1028 mark_key_instantiated(key, 0);1032 mark_key_instantiated(key, 0);
1033 notify_key(key, NOTIFY_KEY_UPDATED, 0);
1034 }
1029 1035
1030 up_write(&key->sem);1036 up_write(&key->sem);
1031 1037
@@ -1057,15 +1063,17 @@ void key_revoke(struct key *key) · 25 unmodified lines
1057 * instantiated1063 * instantiated
1058 */1064 */
1059 down_write_nested(&key->sem, 1);1065 down_write_nested(&key->sem, 1);
1060 if (!test_and_set_bit(KEY_FLAG_REVOKED, &key->flags) &&1066 if (!test_and_set_bit(KEY_FLAG_REVOKED, &key->flags)) {
1061 key->type->revoke)1067 notify_key(key, NOTIFY_KEY_REVOKED, 0);
1062 key->type->revoke(key);1068 if (key->type->revoke)
1063 1069 key->type->revoke(key);
1064 /* set the death time to no more than the expiry time */1070
1065 time = ktime_get_real_seconds();1071 /* set the death time to no more than the expiry time */
1066 if (key->revoked_at == 0 || key->revoked_at > time) {1072 time = ktime_get_real_seconds();
1067 key->revoked_at = time;1073 if (key->revoked_at == 0 || key->revoked_at > time) {
1068 key_schedule_gc(key->revoked_at + key_gc_delay);1074 key->revoked_at = time;
1075 key_schedule_gc(key->revoked_at + key_gc_delay);
1076 }
1069 }1077 }
1070 1078
1071 up_write(&key->sem);1079 up_write(&key->sem);
@@ -1087,8 +1095,10 @@ void key_invalidate(struct key *key) · 15 unmodified lines
1087 1095
1088 if (!test_bit(KEY_FLAG_INVALIDATED, &key->flags)) {1096 if (!test_bit(KEY_FLAG_INVALIDATED, &key->flags)) {
1089 down_write_nested(&key->sem, 1);1097 down_write_nested(&key->sem, 1);
1090 if (!test_and_set_bit(KEY_FLAG_INVALIDATED, &key->flags))1098 if (!test_and_set_bit(KEY_FLAG_INVALIDATED, &key->flags)) {
1099 notify_key(key, NOTIFY_KEY_INVALIDATED, 0);
1091 key_schedule_gc_links();1100 key_schedule_gc_links();
1101 }
1092 up_write(&key->sem);1102 up_write(&key->sem);
1093 }1103 }
1094}1104}
security/keys/keyctl.c+96−3
@@ -37,7 +37,9 @@ static const unsigned char keyrings_capabilities[2] = { · 36 unmodified lines
37 KEYCTL_CAPS0_MOVE37 KEYCTL_CAPS0_MOVE
38 ),38 ),
39 [1] = (KEYCTL_CAPS1_NS_KEYRING_NAME |39 [1] = (KEYCTL_CAPS1_NS_KEYRING_NAME |
40 KEYCTL_CAPS1_NS_KEY_TAG),40 KEYCTL_CAPS1_NS_KEY_TAG |
41 (IS_ENABLED(CONFIG_KEY_NOTIFICATIONS) ? KEYCTL_CAPS1_NOTIFICATIONS : 0)
42 ),
41};43};
42 44
43static int key_get_type_from_user(char *type,45static int key_get_type_from_user(char *type,
@@ -1039,6 +1041,7 @@ long keyctl_chown_key(key_serial_t id, uid_t user, gid_t group) · 995 unmodified lines
1039 if (group != (gid_t) -1)1041 if (group != (gid_t) -1)
1040 key->gid = gid;1042 key->gid = gid;
1041 1043
1044 notify_key(key, NOTIFY_KEY_SETATTR, 0);
1042 ret = 0;1045 ret = 0;
1043 1046
1044error_put:1047error_put:
@@ -1089,6 +1092,7 @@ long keyctl_setperm_key(key_serial_t id, key_perm_t perm) · 44 unmodified lines
1089 /* if we're not the sysadmin, we can only change a key that we own */1092 /* if we're not the sysadmin, we can only change a key that we own */
1090 if (capable(CAP_SYS_ADMIN) || uid_eq(key->uid, current_fsuid())) {1093 if (capable(CAP_SYS_ADMIN) || uid_eq(key->uid, current_fsuid())) {
1091 key->perm = perm;1094 key->perm = perm;
1095 notify_key(key, NOTIFY_KEY_SETATTR, 0);
1092 ret = 0;1096 ret = 0;
1093 }1097 }
1094 1098
@@ -1480,10 +1484,12 @@ long keyctl_set_timeout(key_serial_t id, unsigned timeout) · 385 unmodified lines
1480okay:1484okay:
1481 key = key_ref_to_ptr(key_ref);1485 key = key_ref_to_ptr(key_ref);
1482 ret = 0;1486 ret = 0;
1483 if (test_bit(KEY_FLAG_KEEP, &key->flags))1487 if (test_bit(KEY_FLAG_KEEP, &key->flags)) {
1484 ret = -EPERM;1488 ret = -EPERM;
1485 else1489 } else {
1486 key_set_timeout(key, timeout);1490 key_set_timeout(key, timeout);
1491 notify_key(key, NOTIFY_KEY_SETATTR, 0);
1492 }
1487 key_put(key);1493 key_put(key);
1488 1494
1489error:1495error:
@@ -1757,6 +1763,90 @@ error: · 267 unmodified lines
1757 return ret;1763 return ret;
1758}1764}
1759 1765
1766#ifdef CONFIG_KEY_NOTIFICATIONS
1767/*
1768 * Watch for changes to a key.
1769 *
1770 * The caller must have View permission to watch a key or keyring.
1771 */
1772long keyctl_watch_key(key_serial_t id, int watch_queue_fd, int watch_id)
1773{
1774 struct watch_queue *wqueue;
1775 struct watch_list *wlist = NULL;
1776 struct watch *watch = NULL;
1777 struct key *key;
1778 key_ref_t key_ref;
1779 long ret;
1780
1781 if (watch_id < -1 || watch_id > 0xff)
1782 return -EINVAL;
1783
1784 key_ref = lookup_user_key(id, KEY_LOOKUP_CREATE, KEY_NEED_VIEW);
1785 if (IS_ERR(key_ref))
1786 return PTR_ERR(key_ref);
1787 key = key_ref_to_ptr(key_ref);
1788
1789 wqueue = get_watch_queue(watch_queue_fd);
1790 if (IS_ERR(wqueue)) {
1791 ret = PTR_ERR(wqueue);
1792 goto err_key;
1793 }
1794
1795 if (watch_id >= 0) {
1796 ret = -ENOMEM;
1797 if (!key->watchers) {
1798 wlist = kzalloc(sizeof(*wlist), GFP_KERNEL);
1799 if (!wlist)
1800 goto err_wqueue;
1801 init_watch_list(wlist, NULL);
1802 }
1803
1804 watch = kzalloc(sizeof(*watch), GFP_KERNEL);
1805 if (!watch)
1806 goto err_wlist;
1807
1808 init_watch(watch, wqueue);
1809 watch->id = key->serial;
1810 watch->info_id = (u32)watch_id << WATCH_INFO_ID__SHIFT;
1811
1812 ret = security_watch_key(key);
1813 if (ret < 0)
1814 goto err_watch;
1815
1816 down_write(&key->sem);
1817 if (!key->watchers) {
1818 key->watchers = wlist;
1819 wlist = NULL;
1820 }
1821
1822 ret = add_watch_to_object(watch, key->watchers);
1823 up_write(&key->sem);
1824
1825 if (ret == 0)
1826 watch = NULL;
1827 } else {
1828 ret = -EBADSLT;
1829 if (key->watchers) {
1830 down_write(&key->sem);
1831 ret = remove_watch_from_object(key->watchers,
1832 wqueue, key_serial(key),
1833 false);
1834 up_write(&key->sem);
1835 }
1836 }
1837
1838err_watch:
1839 kfree(watch);
1840err_wlist:
1841 kfree(wlist);
1842err_wqueue:
1843 put_watch_queue(wqueue);
1844err_key:
1845 key_put(key);
1846 return ret;
1847}
1848#endif /* CONFIG_KEY_NOTIFICATIONS */
1849
1760/*1850/*
1761 * Get keyrings subsystem capabilities.1851 * Get keyrings subsystem capabilities.
1762 */1852 */
@@ -1926,6 +2016,9 @@ SYSCALL_DEFINE5(keyctl, int, option, unsigned long, arg2, unsigned long, arg3, · 163 unmodified lines
1926 case KEYCTL_CAPABILITIES:2016 case KEYCTL_CAPABILITIES:
1927 return keyctl_capabilities((unsigned char __user *)arg2, (size_t)arg3);2017 return keyctl_capabilities((unsigned char __user *)arg2, (size_t)arg3);
1928 2018
2019 case KEYCTL_WATCH_KEY:
2020 return keyctl_watch_key((key_serial_t)arg2, (int)arg3, (int)arg4);
2021
1929 default:2022 default:
1930 return -EOPNOTSUPP;2023 return -EOPNOTSUPP;
1931 }2024 }
security/keys/keyring.c+13−7
@@ -1056,12 +1056,14 @@ int keyring_restrict(key_ref_t keyring_ref, const char *type, · 1055 unmodified lines
1056 down_write(&keyring->sem);1056 down_write(&keyring->sem);
1057 down_write(&keyring_serialise_restrict_sem);1057 down_write(&keyring_serialise_restrict_sem);
1058 1058
1059 if (keyring->restrict_link)1059 if (keyring->restrict_link) {
1060 ret = -EEXIST;1060 ret = -EEXIST;
1061 else if (keyring_detect_restriction_cycle(keyring, restrict_link))1061 } else if (keyring_detect_restriction_cycle(keyring, restrict_link)) {
1062 ret = -EDEADLK;1062 ret = -EDEADLK;
1063 else1063 } else {
1064 keyring->restrict_link = restrict_link;1064 keyring->restrict_link = restrict_link;
1065 notify_key(keyring, NOTIFY_KEY_SETATTR, 0);
1066 }
1065 1067
1066 up_write(&keyring_serialise_restrict_sem);1068 up_write(&keyring_serialise_restrict_sem);
1067 up_write(&keyring->sem);1069 up_write(&keyring->sem);
@@ -1362,12 +1364,14 @@ int __key_link_check_live_key(struct key *keyring, struct key *key) · 294 unmodified lines
1362 * holds at most one link to any given key of a particular type+description1364 * holds at most one link to any given key of a particular type+description
1363 * combination.1365 * combination.
1364 */1366 */
1365void __key_link(struct key *key, struct assoc_array_edit **_edit)1367void __key_link(struct key *keyring, struct key *key,
1368 struct assoc_array_edit **_edit)
1366{1369{
1367 __key_get(key);1370 __key_get(key);
1368 assoc_array_insert_set_object(*_edit, keyring_key_to_ptr(key));1371 assoc_array_insert_set_object(*_edit, keyring_key_to_ptr(key));
1369 assoc_array_apply_edit(*_edit);1372 assoc_array_apply_edit(*_edit);
1370 *_edit = NULL;1373 *_edit = NULL;
1374 notify_key(keyring, NOTIFY_KEY_LINKED, key_serial(key));
1371}1375}
1372 1376
1373/*1377/*
@@ -1451,7 +1455,7 @@ int key_link(struct key *keyring, struct key *key) · 77 unmodified lines
1451 if (ret == 0)1455 if (ret == 0)
1452 ret = __key_link_check_live_key(keyring, key);1456 ret = __key_link_check_live_key(keyring, key);
1453 if (ret == 0)1457 if (ret == 0)
1454 __key_link(key, &edit);1458 __key_link(keyring, key, &edit);
1455 1459
1456error_end:1460error_end:
1457 __key_link_end(keyring, &key->index_key, edit);1461 __key_link_end(keyring, &key->index_key, edit);
@@ -1483,7 +1487,7 @@ static int __key_unlink_begin(struct key *keyring, struct key *key, · 25 unmodified lines
1483 struct assoc_array_edit *edit;1487 struct assoc_array_edit *edit;
1484 1488
1485 BUG_ON(*_edit != NULL);1489 BUG_ON(*_edit != NULL);
1486 1490
1487 edit = assoc_array_delete(&keyring->keys, &keyring_assoc_array_ops,1491 edit = assoc_array_delete(&keyring->keys, &keyring_assoc_array_ops,
1488 &key->index_key);1492 &key->index_key);
1489 if (IS_ERR(edit))1493 if (IS_ERR(edit))
@@ -1503,6 +1507,7 @@ static void __key_unlink(struct key *keyring, struct key *key, · 13 unmodified lines
1503 struct assoc_array_edit **_edit)1507 struct assoc_array_edit **_edit)
1504{1508{
1505 assoc_array_apply_edit(*_edit);1509 assoc_array_apply_edit(*_edit);
1510 notify_key(keyring, NOTIFY_KEY_UNLINKED, key_serial(key));
1506 *_edit = NULL;1511 *_edit = NULL;
1507 key_payload_reserve(keyring, keyring->datalen - KEYQUOTA_LINK_BYTES);1512 key_payload_reserve(keyring, keyring->datalen - KEYQUOTA_LINK_BYTES);
1508}1513}
@@ -1621,7 +1626,7 @@ int key_move(struct key *key, · 112 unmodified lines
1621 goto error;1626 goto error;
1622 1627
1623 __key_unlink(from_keyring, key, &from_edit);1628 __key_unlink(from_keyring, key, &from_edit);
1624 __key_link(key, &to_edit);1629 __key_link(to_keyring, key, &to_edit);
1625error:1630error:
1626 __key_link_end(to_keyring, &key->index_key, to_edit);1631 __key_link_end(to_keyring, &key->index_key, to_edit);
1627 __key_unlink_end(from_keyring, key, from_edit);1632 __key_unlink_end(from_keyring, key, from_edit);
@@ -1655,6 +1660,7 @@ int keyring_clear(struct key *keyring) · 27 unmodified lines
1655 } else {1660 } else {
1656 if (edit)1661 if (edit)
1657 assoc_array_apply_edit(edit);1662 assoc_array_apply_edit(edit);
1663 notify_key(keyring, NOTIFY_KEY_CLEARED, 0);
1658 key_payload_reserve(keyring, 0);1664 key_payload_reserve(keyring, 0);
1659 ret = 0;1665 ret = 0;
1660 }1666 }
security/keys/request_key.c+2−2
@@ -418,7 +418,7 @@ static int construct_alloc_key(struct keyring_search_context *ctx, · 417 unmodified lines
418 goto key_already_present;418 goto key_already_present;
419 419
420 if (dest_keyring)420 if (dest_keyring)
421 __key_link(key, &edit);421 __key_link(dest_keyring, key, &edit);
422 422
423 mutex_unlock(&key_construction_mutex);423 mutex_unlock(&key_construction_mutex);
424 if (dest_keyring)424 if (dest_keyring)
@@ -437,7 +437,7 @@ key_already_present: · 12 unmodified lines
437 if (dest_keyring) {437 if (dest_keyring) {
438 ret = __key_link_check_live_key(dest_keyring, key);438 ret = __key_link_check_live_key(dest_keyring, key);
439 if (ret == 0)439 if (ret == 0)
440 __key_link(key, &edit);440 __key_link(dest_keyring, key, &edit);
441 __key_link_end(dest_keyring, &ctx->index_key, edit);441 __key_link_end(dest_keyring, &ctx->index_key, edit);
442 if (ret < 0)442 if (ret < 0)
443 goto link_check_failed;443 goto link_check_failed;