--- zzzz-none-000/linux-3.10.107/Documentation/security/keys.txt 2017-06-27 09:49:32.000000000 +0000 +++ scorpion-7490-727/linux-3.10.107/Documentation/security/keys.txt 2021-02-04 17:41:59.000000000 +0000 @@ -323,8 +323,6 @@ U Under construction by callback to userspace N Negative key - This file must be enabled at kernel configuration time as it allows anyone - to list the keys database. (*) /proc/key-users @@ -865,15 +863,14 @@ calling processes has a searchable link to the key from one of its keyrings. There are three functions for dealing with these: - key_ref_t make_key_ref(const struct key *key, - unsigned long possession); + key_ref_t make_key_ref(const struct key *key, bool possession); struct key *key_ref_to_ptr(const key_ref_t key_ref); - unsigned long is_key_possessed(const key_ref_t key_ref); + bool is_key_possessed(const key_ref_t key_ref); The first function constructs a key reference from a key pointer and - possession information (which must be 0 or 1 and not any other value). + possession information (which must be true or false). The second function retrieves the key pointer from a reference and the third retrieves the possession flag. @@ -889,11 +886,11 @@ const char *callout_info); This is used to request a key or keyring with a description that matches - the description specified according to the key type's match function. This - permits approximate matching to occur. If callout_string is not NULL, then - /sbin/request-key will be invoked in an attempt to obtain the key from - userspace. In that case, callout_string will be passed as an argument to - the program. + the description specified according to the key type's match_preparse() + method. This permits approximate matching to occur. If callout_string is + not NULL, then /sbin/request-key will be invoked in an attempt to obtain + the key from userspace. In that case, callout_string will be passed as an + argument to the program. Should the function fail error ENOKEY, EKEYEXPIRED or EKEYREVOKED will be returned. @@ -961,14 +958,17 @@ the argument will not be parsed. -(*) Extra references can be made to a key by calling the following function: +(*) Extra references can be made to a key by calling one of the following + functions: + struct key *__key_get(struct key *key); struct key *key_get(struct key *key); - These need to be disposed of by calling key_put() when they've been - finished with. The key pointer passed in will be returned. If the pointer - is NULL or CONFIG_KEYS is not set then the key will not be dereferenced and - no increment will take place. + Keys so references will need to be disposed of by calling key_put() when + they've been finished with. The key pointer passed in will be returned. + + In the case of key_get(), if the pointer is NULL or CONFIG_KEYS is not set + then the key will not be dereferenced and no increment will take place. (*) A key's serial number can be obtained by calling: @@ -1049,12 +1049,12 @@ NOTES ON ACCESSING PAYLOAD CONTENTS =================================== -The simplest payload is just a number in key->payload.value. In this case, -there's no need to indulge in RCU or locking when accessing the payload. +The simplest payload is just data stored in key->payload directly. In this +case, there's no need to indulge in RCU or locking when accessing the payload. -More complex payload contents must be allocated and a pointer to them set in -key->payload.data. One of the following ways must be selected to access the -data: +More complex payload contents must be allocated and pointers to them set in the +key->payload.data[] array. One of the following ways must be selected to +access the data: (1) Unmodifiable key type. @@ -1092,6 +1092,13 @@ the payload. key->datalen cannot be relied upon to be consistent with the payload just dereferenced if the key's semaphore is not held. + Note that key->payload.data[0] has a shadow that is marked for __rcu + usage. This is called key->payload.rcu_data0. The following accessors + wrap the RCU calls to this element: + + rcu_assign_keypointer(struct key *key, void *data); + void *rcu_dereference_key(struct key *key); + =================== DEFINING A KEY TYPE @@ -1143,34 +1150,37 @@ struct key_preparsed_payload { char *description; - void *type_data[2]; - void *payload; + union key_payload payload; const void *data; size_t datalen; size_t quotalen; + time_t expiry; }; Before calling the method, the caller will fill in data and datalen with the payload blob parameters; quotalen will be filled in with the default - quota size from the key type and the rest will be cleared. + quota size from the key type; expiry will be set to TIME_T_MAX and the + rest will be cleared. If a description can be proposed from the payload contents, that should be attached as a string to the description field. This will be used for the key description if the caller of add_key() passes NULL or "". - The method can attach anything it likes to type_data[] and payload. These - are merely passed along to the instantiate() or update() operations. + The method can attach anything it likes to payload. This is merely passed + along to the instantiate() or update() operations. If set, the expiry + time will be applied to the key if it is instantiated from this data. - The method should return 0 if success ful or a negative error code + The method should return 0 if successful or a negative error code otherwise. - + (*) void (*free_preparse)(struct key_preparsed_payload *prep); This method is only required if the preparse() method is provided, - otherwise it is unused. It cleans up anything attached to the - description, type_data and payload fields of the key_preparsed_payload - struct as filled in by the preparse() method. + otherwise it is unused. It cleans up anything attached to the description + and payload fields of the key_preparsed_payload struct as filled in by the + preparse() method. It will always be called after preparse() returns + successfully, even if instantiate() or update() succeed. (*) int (*instantiate)(struct key *key, struct key_preparsed_payload *prep); @@ -1191,6 +1201,11 @@ It is safe to sleep in this method. + generic_key_instantiate() is provided to simply copy the data from + prep->payload.data[] to key->payload.data[], with RCU-safe assignment on + the first element. It will then clear prep->payload.data[] so that the + free_preparse method doesn't release the data. + (*) int (*update)(struct key *key, const void *data, size_t datalen); @@ -1217,16 +1232,55 @@ It is safe to sleep in this method. - (*) int (*match)(const struct key *key, const void *desc); + (*) int (*match_preparse)(struct key_match_data *match_data); + + This method is optional. It is called when a key search is about to be + performed. It is given the following structure: + + struct key_match_data { + bool (*cmp)(const struct key *key, + const struct key_match_data *match_data); + const void *raw_data; + void *preparsed; + unsigned lookup_type; + }; + + On entry, raw_data will be pointing to the criteria to be used in matching + a key by the caller and should not be modified. (*cmp)() will be pointing + to the default matcher function (which does an exact description match + against raw_data) and lookup_type will be set to indicate a direct lookup. + + The following lookup_type values are available: + + [*] KEYRING_SEARCH_LOOKUP_DIRECT - A direct lookup hashes the type and + description to narrow down the search to a small number of keys. + + [*] KEYRING_SEARCH_LOOKUP_ITERATE - An iterative lookup walks all the + keys in the keyring until one is matched. This must be used for any + search that's not doing a simple direct match on the key description. + + The method may set cmp to point to a function of its choice that does some + other form of match, may set lookup_type to KEYRING_SEARCH_LOOKUP_ITERATE + and may attach something to the preparsed pointer for use by (*cmp)(). + (*cmp)() should return true if a key matches and false otherwise. + + If preparsed is set, it may be necessary to use the match_free() method to + clean it up. + + The method should return 0 if successful or a negative error code + otherwise. + + It is permitted to sleep in this method, but (*cmp)() may not sleep as + locks will be held over it. + + If match_preparse() is not provided, keys of this type will be matched + exactly by their description. - This method is called to match a key against a description. It should - return non-zero if the two match, zero if they don't. - This method should not need to lock the key in any way. The type and - description can be considered invariant, and the payload should not be - accessed (the key may not yet be instantiated). + (*) void (*match_free)(struct key_match_data *match_data); - It is not safe to sleep in this method; the caller may hold spinlocks. + This method is optional. If given, it called to clean up + match_data->preparsed after a successful call to match_preparse(). (*) void (*revoke)(struct key *key);