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
6969 #define KEYCTL_RESTRICT_KEYRING 29 /* Restrict keys allowed to link to a keyring */
7070 #define KEYCTL_MOVE 30 /* Move keys between keyrings */
7171 #define KEYCTL_CAPABILITIES 31 /* Find capabilities of keyrings subsystem */
72+#define KEYCTL_WATCH_KEY 32 /* Watch a key or ring of keys for changes */
7273
7374 /* keyctl structures */
7475 struct keyctl_dh_params {
@@ -130,5 +131,6 @@ struct keyctl_pkey_params { · 55 unmodified lines
130131 #define KEYCTL_CAPS0_MOVE 0x80 /* KEYCTL_MOVE supported */
131132 #define KEYCTL_CAPS1_NS_KEYRING_NAME 0x01 /* Keyring names are per-user_namespace */
132133 #define KEYCTL_CAPS1_NS_KEY_TAG 0x02 /* Key indexing can include a namespace tag */
134+#define KEYCTL_CAPS1_NOTIFICATIONS 0x04 /* Keys generate watchable notifications */
133135
134136 #endif /* _LINUX_KEYCTL_H */
include/uapi/linux/watch_queue.h+27−1
@@ -13,7 +13,8 @@ · 12 unmodified lines
1313
1414 enum watch_notification_type {
1515 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
1718 };
1819
1920 enum watch_meta_notification_subtype {
@@ -75,4 +76,29 @@ struct watch_notification_removal { · 55 unmodified lines
7576 __u64 id; /* Type-dependent identifier */
7677 };
7778
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+
78104 #endif /* _UAPI_LINUX_WATCH_QUEUE_H */