Loading Documentation/security/keys.txt +49 −1 Original line number Diff line number Diff line Loading @@ -412,6 +412,10 @@ The main syscalls are: to the keyring. In this case, an error will be generated if the process does not have permission to write to the keyring. If the key type supports it, if the description is NULL or an empty string, the key type will try and generate a description from the content of the payload. The payload is optional, and the pointer can be NULL if not required by the type. The payload is plen in size, and plen can be zero for an empty payload. Loading Loading @@ -1131,12 +1135,53 @@ The structure has a number of fields, some of which are mandatory: it should return 0. (*) int (*instantiate)(struct key *key, const void *data, size_t datalen); (*) int (*preparse)(struct key_preparsed_payload *prep); This optional method permits the key type to attempt to parse payload before a key is created (add key) or the key semaphore is taken (update or instantiate key). The structure pointed to by prep looks like: struct key_preparsed_payload { char *description; void *type_data[2]; void *payload; const void *data; size_t datalen; size_t quotalen; }; 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. 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 should return 0 if success ful 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. (*) int (*instantiate)(struct key *key, struct key_preparsed_payload *prep); This method is called to attach a payload to a key during construction. The payload attached need not bear any relation to the data passed to this function. The prep->data and prep->datalen fields will define the original payload blob. If preparse() was supplied then other fields may be filled in also. If the amount of data attached to the key differs from the size in keytype->def_datalen, then key_payload_reserve() should be called. Loading @@ -1152,6 +1197,9 @@ The structure has a number of fields, some of which are mandatory: If this type of key can be updated, then this method should be provided. It is called to update a key's payload from the blob of data provided. The prep->data and prep->datalen fields will define the original payload blob. If preparse() was supplied then other fields may be filled in also. key_payload_reserve() should be called if the data length might change before any changes are actually made. Note that if this succeeds, the type is committed to changing the key because it's already been altered, so all Loading fs/cifs/cifs_spnego.c +3 −3 Original line number Diff line number Diff line Loading @@ -31,18 +31,18 @@ /* create a new cifs key */ static int cifs_spnego_key_instantiate(struct key *key, const void *data, size_t datalen) cifs_spnego_key_instantiate(struct key *key, struct key_preparsed_payload *prep) { char *payload; int ret; ret = -ENOMEM; payload = kmalloc(datalen, GFP_KERNEL); payload = kmalloc(prep->datalen, GFP_KERNEL); if (!payload) goto error; /* attach the data */ memcpy(payload, data, datalen); memcpy(payload, prep->data, prep->datalen); key->payload.data = payload; ret = 0; Loading fs/cifs/cifsacl.c +4 −4 Original line number Diff line number Diff line Loading @@ -167,17 +167,17 @@ static struct shrinker cifs_shrinker = { }; static int cifs_idmap_key_instantiate(struct key *key, const void *data, size_t datalen) cifs_idmap_key_instantiate(struct key *key, struct key_preparsed_payload *prep) { char *payload; payload = kmalloc(datalen, GFP_KERNEL); payload = kmalloc(prep->datalen, GFP_KERNEL); if (!payload) return -ENOMEM; memcpy(payload, data, datalen); memcpy(payload, prep->data, prep->datalen); key->payload.data = payload; key->datalen = datalen; key->datalen = prep->datalen; return 0; } Loading include/keys/user-type.h +4 −2 Original line number Diff line number Diff line Loading @@ -35,8 +35,10 @@ struct user_key_payload { extern struct key_type key_type_user; extern struct key_type key_type_logon; extern int user_instantiate(struct key *key, const void *data, size_t datalen); extern int user_update(struct key *key, const void *data, size_t datalen); struct key_preparsed_payload; extern int user_instantiate(struct key *key, struct key_preparsed_payload *prep); extern int user_update(struct key *key, struct key_preparsed_payload *prep); extern int user_match(const struct key *key, const void *criterion); extern void user_revoke(struct key *key); extern void user_destroy(struct key *key); Loading include/linux/key-type.h +33 −2 Original line number Diff line number Diff line Loading @@ -26,6 +26,27 @@ struct key_construction { struct key *authkey;/* authorisation for key being constructed */ }; /* * Pre-parsed payload, used by key add, update and instantiate. * * This struct will be cleared and data and datalen will be set with the data * and length parameters from the caller and quotalen will be set from * def_datalen from the key type. Then if the preparse() op is provided by the * key type, that will be called. Then the struct will be passed to the * instantiate() or the update() op. * * If the preparse() op is given, the free_preparse() op will be called to * clear the contents. */ struct key_preparsed_payload { char *description; /* Proposed key description (or NULL) */ void *type_data[2]; /* Private key-type data */ void *payload; /* Proposed payload */ const void *data; /* Raw data */ size_t datalen; /* Raw datalen */ size_t quotalen; /* Quota length for proposed payload */ }; typedef int (*request_key_actor_t)(struct key_construction *key, const char *op, void *aux); Loading @@ -45,18 +66,28 @@ struct key_type { /* vet a description */ int (*vet_description)(const char *description); /* Preparse the data blob from userspace that is to be the payload, * generating a proposed description and payload that will be handed to * the instantiate() and update() ops. */ int (*preparse)(struct key_preparsed_payload *prep); /* Free a preparse data structure. */ void (*free_preparse)(struct key_preparsed_payload *prep); /* instantiate a key of this type * - this method should call key_payload_reserve() to determine if the * user's quota will hold the payload */ int (*instantiate)(struct key *key, const void *data, size_t datalen); int (*instantiate)(struct key *key, struct key_preparsed_payload *prep); /* update a key of this type (optional) * - this method should call key_payload_reserve() to recalculate the * quota consumption * - the key must be locked against read when modifying */ int (*update)(struct key *key, const void *data, size_t datalen); int (*update)(struct key *key, struct key_preparsed_payload *prep); /* match a key against a description */ int (*match)(const struct key *key, const void *desc); Loading Loading
Documentation/security/keys.txt +49 −1 Original line number Diff line number Diff line Loading @@ -412,6 +412,10 @@ The main syscalls are: to the keyring. In this case, an error will be generated if the process does not have permission to write to the keyring. If the key type supports it, if the description is NULL or an empty string, the key type will try and generate a description from the content of the payload. The payload is optional, and the pointer can be NULL if not required by the type. The payload is plen in size, and plen can be zero for an empty payload. Loading Loading @@ -1131,12 +1135,53 @@ The structure has a number of fields, some of which are mandatory: it should return 0. (*) int (*instantiate)(struct key *key, const void *data, size_t datalen); (*) int (*preparse)(struct key_preparsed_payload *prep); This optional method permits the key type to attempt to parse payload before a key is created (add key) or the key semaphore is taken (update or instantiate key). The structure pointed to by prep looks like: struct key_preparsed_payload { char *description; void *type_data[2]; void *payload; const void *data; size_t datalen; size_t quotalen; }; 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. 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 should return 0 if success ful 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. (*) int (*instantiate)(struct key *key, struct key_preparsed_payload *prep); This method is called to attach a payload to a key during construction. The payload attached need not bear any relation to the data passed to this function. The prep->data and prep->datalen fields will define the original payload blob. If preparse() was supplied then other fields may be filled in also. If the amount of data attached to the key differs from the size in keytype->def_datalen, then key_payload_reserve() should be called. Loading @@ -1152,6 +1197,9 @@ The structure has a number of fields, some of which are mandatory: If this type of key can be updated, then this method should be provided. It is called to update a key's payload from the blob of data provided. The prep->data and prep->datalen fields will define the original payload blob. If preparse() was supplied then other fields may be filled in also. key_payload_reserve() should be called if the data length might change before any changes are actually made. Note that if this succeeds, the type is committed to changing the key because it's already been altered, so all Loading
fs/cifs/cifs_spnego.c +3 −3 Original line number Diff line number Diff line Loading @@ -31,18 +31,18 @@ /* create a new cifs key */ static int cifs_spnego_key_instantiate(struct key *key, const void *data, size_t datalen) cifs_spnego_key_instantiate(struct key *key, struct key_preparsed_payload *prep) { char *payload; int ret; ret = -ENOMEM; payload = kmalloc(datalen, GFP_KERNEL); payload = kmalloc(prep->datalen, GFP_KERNEL); if (!payload) goto error; /* attach the data */ memcpy(payload, data, datalen); memcpy(payload, prep->data, prep->datalen); key->payload.data = payload; ret = 0; Loading
fs/cifs/cifsacl.c +4 −4 Original line number Diff line number Diff line Loading @@ -167,17 +167,17 @@ static struct shrinker cifs_shrinker = { }; static int cifs_idmap_key_instantiate(struct key *key, const void *data, size_t datalen) cifs_idmap_key_instantiate(struct key *key, struct key_preparsed_payload *prep) { char *payload; payload = kmalloc(datalen, GFP_KERNEL); payload = kmalloc(prep->datalen, GFP_KERNEL); if (!payload) return -ENOMEM; memcpy(payload, data, datalen); memcpy(payload, prep->data, prep->datalen); key->payload.data = payload; key->datalen = datalen; key->datalen = prep->datalen; return 0; } Loading
include/keys/user-type.h +4 −2 Original line number Diff line number Diff line Loading @@ -35,8 +35,10 @@ struct user_key_payload { extern struct key_type key_type_user; extern struct key_type key_type_logon; extern int user_instantiate(struct key *key, const void *data, size_t datalen); extern int user_update(struct key *key, const void *data, size_t datalen); struct key_preparsed_payload; extern int user_instantiate(struct key *key, struct key_preparsed_payload *prep); extern int user_update(struct key *key, struct key_preparsed_payload *prep); extern int user_match(const struct key *key, const void *criterion); extern void user_revoke(struct key *key); extern void user_destroy(struct key *key); Loading
include/linux/key-type.h +33 −2 Original line number Diff line number Diff line Loading @@ -26,6 +26,27 @@ struct key_construction { struct key *authkey;/* authorisation for key being constructed */ }; /* * Pre-parsed payload, used by key add, update and instantiate. * * This struct will be cleared and data and datalen will be set with the data * and length parameters from the caller and quotalen will be set from * def_datalen from the key type. Then if the preparse() op is provided by the * key type, that will be called. Then the struct will be passed to the * instantiate() or the update() op. * * If the preparse() op is given, the free_preparse() op will be called to * clear the contents. */ struct key_preparsed_payload { char *description; /* Proposed key description (or NULL) */ void *type_data[2]; /* Private key-type data */ void *payload; /* Proposed payload */ const void *data; /* Raw data */ size_t datalen; /* Raw datalen */ size_t quotalen; /* Quota length for proposed payload */ }; typedef int (*request_key_actor_t)(struct key_construction *key, const char *op, void *aux); Loading @@ -45,18 +66,28 @@ struct key_type { /* vet a description */ int (*vet_description)(const char *description); /* Preparse the data blob from userspace that is to be the payload, * generating a proposed description and payload that will be handed to * the instantiate() and update() ops. */ int (*preparse)(struct key_preparsed_payload *prep); /* Free a preparse data structure. */ void (*free_preparse)(struct key_preparsed_payload *prep); /* instantiate a key of this type * - this method should call key_payload_reserve() to determine if the * user's quota will hold the payload */ int (*instantiate)(struct key *key, const void *data, size_t datalen); int (*instantiate)(struct key *key, struct key_preparsed_payload *prep); /* update a key of this type (optional) * - this method should call key_payload_reserve() to recalculate the * quota consumption * - the key must be locked against read when modifying */ int (*update)(struct key *key, const void *data, size_t datalen); int (*update)(struct key *key, struct key_preparsed_payload *prep); /* match a key against a description */ int (*match)(const struct key *key, const void *desc); Loading