^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) ==============================
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) General notification mechanism
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) ==============================
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) The general notification mechanism is built on top of the standard pipe driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) whereby it effectively splices notification messages from the kernel into pipes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) opened by userspace. This can be used in conjunction with::
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * Key/keyring notifications
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) The notifications buffers can be enabled by:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) "General setup"/"General notification queue"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) (CONFIG_WATCH_QUEUE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) This document has the following sections:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) .. contents:: :local:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) Overview
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) ========
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) This facility appears as a pipe that is opened in a special mode. The pipe's
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) internal ring buffer is used to hold messages that are generated by the kernel.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) These messages are then read out by read(). Splice and similar are disabled on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) such pipes due to them wanting to, under some circumstances, revert their
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) additions to the ring - which might end up interleaved with notification
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) messages.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) The owner of the pipe has to tell the kernel which sources it would like to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) watch through that pipe. Only sources that have been connected to a pipe will
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) insert messages into it. Note that a source may be bound to multiple pipes and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) insert messages into all of them simultaneously.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) Filters may also be emplaced on a pipe so that certain source types and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) subevents can be ignored if they're not of interest.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) A message will be discarded if there isn't a slot available in the ring or if
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) no preallocated message buffer is available. In both of these cases, read()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) will insert a WATCH_META_LOSS_NOTIFICATION message into the output buffer after
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) the last message currently in the buffer has been read.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) Note that when producing a notification, the kernel does not wait for the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) consumers to collect it, but rather just continues on. This means that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) notifications can be generated whilst spinlocks are held and also protects the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) kernel from being held up indefinitely by a userspace malfunction.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) Message Structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) =================
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) Notification messages begin with a short header::
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) struct watch_notification {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) __u32 type:24;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) __u32 subtype:8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) __u32 info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) "type" indicates the source of the notification record and "subtype" indicates
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) the type of record from that source (see the Watch Sources section below). The
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) type may also be "WATCH_TYPE_META". This is a special record type generated
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) internally by the watch queue itself. There are two subtypes:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) * WATCH_META_REMOVAL_NOTIFICATION
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) * WATCH_META_LOSS_NOTIFICATION
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) The first indicates that an object on which a watch was installed was removed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) or destroyed and the second indicates that some messages have been lost.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) "info" indicates a bunch of things, including:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) * The length of the message in bytes, including the header (mask with
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) WATCH_INFO_LENGTH and shift by WATCH_INFO_LENGTH__SHIFT). This indicates
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) the size of the record, which may be between 8 and 127 bytes.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) * The watch ID (mask with WATCH_INFO_ID and shift by WATCH_INFO_ID__SHIFT).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) This indicates that caller's ID of the watch, which may be between 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) and 255. Multiple watches may share a queue, and this provides a means to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) distinguish them.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) * A type-specific field (WATCH_INFO_TYPE_INFO). This is set by the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) notification producer to indicate some meaning specific to the type and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) subtype.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) Everything in info apart from the length can be used for filtering.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) The header can be followed by supplementary information. The format of this is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) at the discretion is defined by the type and subtype.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) Watch List (Notification Source) API
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) ====================================
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) A "watch list" is a list of watchers that are subscribed to a source of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) notifications. A list may be attached to an object (say a key or a superblock)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) or may be global (say for device events). From a userspace perspective, a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) non-global watch list is typically referred to by reference to the object it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) belongs to (such as using KEYCTL_NOTIFY and giving it a key serial number to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) watch that specific key).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) To manage a watch list, the following functions are provided:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) * ::
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) void init_watch_list(struct watch_list *wlist,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) void (*release_watch)(struct watch *wlist));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) Initialise a watch list. If ``release_watch`` is not NULL, then this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) indicates a function that should be called when the watch_list object is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) destroyed to discard any references the watch list holds on the watched
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) object.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) * ``void remove_watch_list(struct watch_list *wlist);``
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) This removes all of the watches subscribed to a watch_list and frees them
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) and then destroys the watch_list object itself.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) Watch Queue (Notification Output) API
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) =====================================
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) A "watch queue" is the buffer allocated by an application that notification
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) records will be written into. The workings of this are hidden entirely inside
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) of the pipe device driver, but it is necessary to gain a reference to it to set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) a watch. These can be managed with:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) * ``struct watch_queue *get_watch_queue(int fd);``
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) Since watch queues are indicated to the kernel by the fd of the pipe that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) implements the buffer, userspace must hand that fd through a system call.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) This can be used to look up an opaque pointer to the watch queue from the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) system call.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) * ``void put_watch_queue(struct watch_queue *wqueue);``
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) This discards the reference obtained from ``get_watch_queue()``.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) Watch Subscription API
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) ======================
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) A "watch" is a subscription on a watch list, indicating the watch queue, and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) thus the buffer, into which notification records should be written. The watch
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) queue object may also carry filtering rules for that object, as set by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) userspace. Some parts of the watch struct can be set by the driver::
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) struct watch {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) union {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) u32 info_id; /* ID to be OR'd in to info field */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) ...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) void *private; /* Private data for the watched object */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) u64 id; /* Internal identifier */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) ...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) The ``info_id`` value should be an 8-bit number obtained from userspace and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) shifted by WATCH_INFO_ID__SHIFT. This is OR'd into the WATCH_INFO_ID field of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) struct watch_notification::info when and if the notification is written into
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) the associated watch queue buffer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) The ``private`` field is the driver's data associated with the watch_list and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) is cleaned up by the ``watch_list::release_watch()`` method.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) The ``id`` field is the source's ID. Notifications that are posted with a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) different ID are ignored.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) The following functions are provided to manage watches:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) * ``void init_watch(struct watch *watch, struct watch_queue *wqueue);``
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) Initialise a watch object, setting its pointer to the watch queue, using
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) appropriate barriering to avoid lockdep complaints.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) * ``int add_watch_to_object(struct watch *watch, struct watch_list *wlist);``
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) Subscribe a watch to a watch list (notification source). The
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) driver-settable fields in the watch struct must have been set before this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) is called.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) * ::
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) int remove_watch_from_object(struct watch_list *wlist,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) struct watch_queue *wqueue,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) u64 id, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) Remove a watch from a watch list, where the watch must match the specified
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) watch queue (``wqueue``) and object identifier (``id``). A notification
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) (``WATCH_META_REMOVAL_NOTIFICATION``) is sent to the watch queue to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) indicate that the watch got removed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) * ``int remove_watch_from_object(struct watch_list *wlist, NULL, 0, true);``
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) Remove all the watches from a watch list. It is expected that this will be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) called preparatory to destruction and that the watch list will be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) inaccessible to new watches by this point. A notification
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) (``WATCH_META_REMOVAL_NOTIFICATION``) is sent to the watch queue of each
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) subscribed watch to indicate that the watch got removed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) Notification Posting API
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) ========================
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) To post a notification to watch list so that the subscribed watches can see it,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) the following function should be used::
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) void post_watch_notification(struct watch_list *wlist,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) struct watch_notification *n,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) const struct cred *cred,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) u64 id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) The notification should be preformatted and a pointer to the header (``n``)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) should be passed in. The notification may be larger than this and the size in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) units of buffer slots is noted in ``n->info & WATCH_INFO_LENGTH``.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) The ``cred`` struct indicates the credentials of the source (subject) and is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) passed to the LSMs, such as SELinux, to allow or suppress the recording of the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) note in each individual queue according to the credentials of that queue
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) (object).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) The ``id`` is the ID of the source object (such as the serial number on a key).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) Only watches that have the same ID set in them will see this notification.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) Watch Sources
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) =============
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) Any particular buffer can be fed from multiple sources. Sources include:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) * WATCH_TYPE_KEY_NOTIFY
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) Notifications of this type indicate changes to keys and keyrings, including
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) the changes of keyring contents or the attributes of keys.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) See Documentation/security/keys/core.rst for more information.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) Event Filtering
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) ===============
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) Once a watch queue has been created, a set of filters can be applied to limit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) the events that are received using::
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) struct watch_notification_filter filter = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) ...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) ioctl(fd, IOC_WATCH_QUEUE_SET_FILTER, &filter)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) The filter description is a variable of type::
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) struct watch_notification_filter {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) __u32 nr_filters;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) __u32 __reserved;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) struct watch_notification_type_filter filters[];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) Where "nr_filters" is the number of filters in filters[] and "__reserved"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) should be 0. The "filters" array has elements of the following type::
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) struct watch_notification_type_filter {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) __u32 type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) __u32 info_filter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) __u32 info_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) __u32 subtype_filter[8];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) Where:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) * ``type`` is the event type to filter for and should be something like
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) "WATCH_TYPE_KEY_NOTIFY"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) * ``info_filter`` and ``info_mask`` act as a filter on the info field of the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) notification record. The notification is only written into the buffer if::
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) (watch.info & info_mask) == info_filter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) This could be used, for example, to ignore events that are not exactly on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) the watched point in a mount tree.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) * ``subtype_filter`` is a bitmask indicating the subtypes that are of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) interest. Bit 0 of subtype_filter[0] corresponds to subtype 0, bit 1 to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) subtype 1, and so on.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) If the argument to the ioctl() is NULL, then the filters will be removed and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) all events from the watched sources will come through.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) Userspace Code Example
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) ======================
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) A buffer is created with something like the following::
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) pipe2(fds, O_TMPFILE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) ioctl(fds[1], IOC_WATCH_QUEUE_SET_SIZE, 256);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) It can then be set to receive keyring change notifications::
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) keyctl(KEYCTL_WATCH_KEY, KEY_SPEC_SESSION_KEYRING, fds[1], 0x01);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) The notifications can then be consumed by something like the following::
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) static void consumer(int rfd, struct watch_queue_buffer *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) unsigned char buffer[128];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) ssize_t buf_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) while (buf_len = read(rfd, buffer, sizeof(buffer)),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) buf_len > 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) void *p = buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) void *end = buffer + buf_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) while (p < end) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) union {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) struct watch_notification n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) unsigned char buf1[128];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) } n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) size_t largest, len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) largest = end - p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) if (largest > 128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) largest = 128;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) memcpy(&n, p, largest);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) len = (n->info & WATCH_INFO_LENGTH) >>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) WATCH_INFO_LENGTH__SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) if (len == 0 || len > largest)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) switch (n.n.type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) case WATCH_TYPE_META:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) got_meta(&n.n);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) case WATCH_TYPE_KEY_NOTIFY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) saw_key_change(&n.n);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) p += len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) }