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

Showing the changes to include/uapi/linux (2 of 12 files). Show all

Unified · Split

2 files
  1. include/uapi/linux/keyctl.h +2 −0
  2. include/uapi/linux/watch_queue.h +27 −1
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 */