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.
Showing the changes to include/uapi/linux (2 of 12 files). Show all
Unified · Split
| @@ -69,6 +69,7 @@ · 68 unmodified lines | ||
| 69 | 69 | #define KEYCTL_RESTRICT_KEYRING 29 /* Restrict keys allowed to link to a keyring */ |
| 70 | 70 | #define KEYCTL_MOVE 30 /* Move keys between keyrings */ |
| 71 | 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 | 74 | /* keyctl structures */ |
| 74 | 75 | struct keyctl_dh_params { |
| @@ -130,5 +131,6 @@ struct keyctl_pkey_params { · 55 unmodified lines | ||
| 130 | 131 | #define KEYCTL_CAPS0_MOVE 0x80 /* KEYCTL_MOVE supported */ |
| 131 | 132 | #define KEYCTL_CAPS1_NS_KEYRING_NAME 0x01 /* Keyring names are per-user_namespace */ |
| 132 | 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 | 136 | #endif /* _LINUX_KEYCTL_H */ |
| @@ -13,7 +13,8 @@ · 12 unmodified lines | ||
| 13 | 13 | |
| 14 | 14 | enum watch_notification_type { |
| 15 | 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 | 20 | enum watch_meta_notification_subtype { |
| @@ -75,4 +76,29 @@ struct watch_notification_removal { · 55 unmodified lines | ||
| 75 | 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 | 104 | #endif /* _UAPI_LINUX_WATCH_QUEUE_H */ |