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.
Unified · Split
| @@ -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 | |||
| 1029 | Kernel Services | 1086 | Kernel Services |
| 1030 | =============== | 1087 | =============== |
| 1031 | 1088 | ||
| @@ -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 */ |
| @@ -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 */ |
| 74 | struct keyctl_dh_params { | 75 | struct 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 */ |
| @@ -13,7 +13,8 @@ · 12 unmodified lines | |||
| 13 | 13 | ||
| 14 | enum watch_notification_type { | 14 | enum watch_notification_type { |
| 15 | WATCH_TYPE_META = 0, /* Special record */ | 15 | WATCH_TYPE_META = 0, /* Special record */ |
| 16 | WATCH_TYPE__NR = 1 | 16 | WATCH_TYPE_KEY_NOTIFY = 1, /* Key change event notification */ |
| 17 | WATCH_TYPE__NR = 2 | ||
| 17 | }; | 18 | }; |
| 18 | 19 | ||
| 19 | enum watch_meta_notification_subtype { | 20 | enum 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 | */ | ||
| 82 | enum 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 | */ | ||
| 98 | struct 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 */ |
| @@ -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 | |||
| 120 | config 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. | ||
| @@ -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 | } |
| @@ -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); |
| @@ -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); |
| 101 | extern int __key_link_check_live_key(struct key *keyring, struct key *key); | 102 | extern int __key_link_check_live_key(struct key *keyring, struct key *key); |
| 102 | extern void __key_link(struct key *key, struct assoc_array_edit **_edit); | 103 | extern void __key_link(struct key *keyring, struct key *key, |
| 104 | struct assoc_array_edit **_edit); | ||
| 103 | extern void __key_link_end(struct key *keyring, | 105 | extern 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 | ||
| 188 | static 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 | ||
| 334 | extern long keyctl_capabilities(unsigned char __user *_buffer, size_t buflen); | 353 | extern long keyctl_capabilities(unsigned char __user *_buffer, size_t buflen); |
| 335 | 354 | ||
| 355 | #ifdef CONFIG_KEY_NOTIFICATIONS | ||
| 356 | extern long keyctl_watch_key(key_serial_t, int, int); | ||
| 357 | #else | ||
| 358 | static 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 validation | 365 | * Debugging key validation |
| 338 | */ | 366 | */ |
| @@ -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 | * instantiated | 1063 | * 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 | } |
| @@ -37,7 +37,9 @@ static const unsigned char keyrings_capabilities[2] = { · 36 unmodified lines | |||
| 37 | KEYCTL_CAPS0_MOVE | 37 | 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 | ||
| 43 | static int key_get_type_from_user(char *type, | 45 | static 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 | ||
| 1044 | error_put: | 1047 | error_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 | |||
| 1480 | okay: | 1484 | okay: |
| 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 | else | 1489 | } 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 | ||
| 1489 | error: | 1495 | error: |
| @@ -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 | */ | ||
| 1772 | long 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 | |||
| 1838 | err_watch: | ||
| 1839 | kfree(watch); | ||
| 1840 | err_wlist: | ||
| 1841 | kfree(wlist); | ||
| 1842 | err_wqueue: | ||
| 1843 | put_watch_queue(wqueue); | ||
| 1844 | err_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 | } |
| @@ -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 | else | 1063 | } 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+description | 1364 | * holds at most one link to any given key of a particular type+description |
| 1363 | * combination. | 1365 | * combination. |
| 1364 | */ | 1366 | */ |
| 1365 | void __key_link(struct key *key, struct assoc_array_edit **_edit) | 1367 | void __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 | ||
| 1456 | error_end: | 1460 | error_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); |
| 1625 | error: | 1630 | error: |
| 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 | } |
| @@ -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; |