You've already forked linux-apfs
mirror of
https://github.com/linux-apfs/linux-apfs.git
synced 2026-05-01 15:00:59 -07:00
Merge tag 'keys-next-20140922' of git://git.kernel.org/pub/scm/linux/kernel/git/dhowells/linux-fs into next
This commit is contained in:
@@ -33,11 +33,9 @@ MODULE_LICENSE("GPL");
|
||||
*/
|
||||
struct key_type key_type_big_key = {
|
||||
.name = "big_key",
|
||||
.def_lookup_type = KEYRING_SEARCH_LOOKUP_DIRECT,
|
||||
.preparse = big_key_preparse,
|
||||
.free_preparse = big_key_free_preparse,
|
||||
.instantiate = generic_key_instantiate,
|
||||
.match = user_match,
|
||||
.revoke = big_key_revoke,
|
||||
.destroy = big_key_destroy,
|
||||
.describe = big_key_describe,
|
||||
|
||||
@@ -970,7 +970,6 @@ struct key_type key_type_encrypted = {
|
||||
.name = "encrypted",
|
||||
.instantiate = encrypted_instantiate,
|
||||
.update = encrypted_update,
|
||||
.match = user_match,
|
||||
.destroy = encrypted_destroy,
|
||||
.describe = user_describe,
|
||||
.read = encrypted_read,
|
||||
|
||||
+10
-11
@@ -107,20 +107,16 @@ extern int iterate_over_keyring(const struct key *keyring,
|
||||
int (*func)(const struct key *key, void *data),
|
||||
void *data);
|
||||
|
||||
typedef int (*key_match_func_t)(const struct key *, const void *);
|
||||
|
||||
struct keyring_search_context {
|
||||
struct keyring_index_key index_key;
|
||||
const struct cred *cred;
|
||||
key_match_func_t match;
|
||||
const void *match_data;
|
||||
struct key_match_data match_data;
|
||||
unsigned flags;
|
||||
#define KEYRING_SEARCH_LOOKUP_TYPE 0x0001 /* [as type->def_lookup_type] */
|
||||
#define KEYRING_SEARCH_NO_STATE_CHECK 0x0002 /* Skip state checks */
|
||||
#define KEYRING_SEARCH_DO_STATE_CHECK 0x0004 /* Override NO_STATE_CHECK */
|
||||
#define KEYRING_SEARCH_NO_UPDATE_TIME 0x0008 /* Don't update times */
|
||||
#define KEYRING_SEARCH_NO_CHECK_PERM 0x0010 /* Don't check permissions */
|
||||
#define KEYRING_SEARCH_DETECT_TOO_DEEP 0x0020 /* Give an error on excessive depth */
|
||||
#define KEYRING_SEARCH_NO_STATE_CHECK 0x0001 /* Skip state checks */
|
||||
#define KEYRING_SEARCH_DO_STATE_CHECK 0x0002 /* Override NO_STATE_CHECK */
|
||||
#define KEYRING_SEARCH_NO_UPDATE_TIME 0x0004 /* Don't update times */
|
||||
#define KEYRING_SEARCH_NO_CHECK_PERM 0x0008 /* Don't check permissions */
|
||||
#define KEYRING_SEARCH_DETECT_TOO_DEEP 0x0010 /* Give an error on excessive depth */
|
||||
|
||||
int (*iterator)(const void *object, void *iterator_data);
|
||||
|
||||
@@ -131,6 +127,8 @@ struct keyring_search_context {
|
||||
struct timespec now;
|
||||
};
|
||||
|
||||
extern bool key_default_cmp(const struct key *key,
|
||||
const struct key_match_data *match_data);
|
||||
extern key_ref_t keyring_search_aux(key_ref_t keyring_ref,
|
||||
struct keyring_search_context *ctx);
|
||||
|
||||
@@ -152,7 +150,8 @@ extern struct key *request_key_and_link(struct key_type *type,
|
||||
struct key *dest_keyring,
|
||||
unsigned long flags);
|
||||
|
||||
extern int lookup_user_key_possessed(const struct key *key, const void *target);
|
||||
extern bool lookup_user_key_possessed(const struct key *key,
|
||||
const struct key_match_data *match_data);
|
||||
extern key_ref_t lookup_user_key(key_serial_t id, unsigned long flags,
|
||||
key_perm_t perm);
|
||||
#define KEY_LOOKUP_CREATE 0x01
|
||||
|
||||
+1
-1
@@ -799,7 +799,7 @@ key_ref_t key_create_or_update(key_ref_t keyring_ref,
|
||||
}
|
||||
|
||||
key_ref = ERR_PTR(-EINVAL);
|
||||
if (!index_key.type->match || !index_key.type->instantiate ||
|
||||
if (!index_key.type->instantiate ||
|
||||
(!index_key.description && !index_key.type->preparse))
|
||||
goto error_put_type;
|
||||
|
||||
|
||||
@@ -37,6 +37,8 @@ static int key_get_type_from_user(char *type,
|
||||
return ret;
|
||||
if (ret == 0 || ret >= len)
|
||||
return -EINVAL;
|
||||
if (type[0] == '.')
|
||||
return -EPERM;
|
||||
type[len - 1] = '\0';
|
||||
return 0;
|
||||
}
|
||||
|
||||
+37
-21
@@ -89,7 +89,6 @@ struct key_type key_type_keyring = {
|
||||
.preparse = keyring_preparse,
|
||||
.free_preparse = keyring_free_preparse,
|
||||
.instantiate = keyring_instantiate,
|
||||
.match = user_match,
|
||||
.revoke = keyring_revoke,
|
||||
.destroy = keyring_destroy,
|
||||
.describe = keyring_describe,
|
||||
@@ -511,6 +510,15 @@ struct key *keyring_alloc(const char *description, kuid_t uid, kgid_t gid,
|
||||
}
|
||||
EXPORT_SYMBOL(keyring_alloc);
|
||||
|
||||
/*
|
||||
* By default, we keys found by getting an exact match on their descriptions.
|
||||
*/
|
||||
bool key_default_cmp(const struct key *key,
|
||||
const struct key_match_data *match_data)
|
||||
{
|
||||
return strcmp(key->description, match_data->raw_data) == 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Iteration function to consider each key found.
|
||||
*/
|
||||
@@ -545,7 +553,7 @@ static int keyring_search_iterator(const void *object, void *iterator_data)
|
||||
}
|
||||
|
||||
/* keys that don't match */
|
||||
if (!ctx->match(key, ctx->match_data)) {
|
||||
if (!ctx->match_data.cmp(key, &ctx->match_data)) {
|
||||
kleave(" = 0 [!match]");
|
||||
return 0;
|
||||
}
|
||||
@@ -585,8 +593,7 @@ skipped:
|
||||
*/
|
||||
static int search_keyring(struct key *keyring, struct keyring_search_context *ctx)
|
||||
{
|
||||
if ((ctx->flags & KEYRING_SEARCH_LOOKUP_TYPE) ==
|
||||
KEYRING_SEARCH_LOOKUP_DIRECT) {
|
||||
if (ctx->match_data.lookup_type == KEYRING_SEARCH_LOOKUP_DIRECT) {
|
||||
const void *object;
|
||||
|
||||
object = assoc_array_find(&keyring->keys,
|
||||
@@ -627,7 +634,7 @@ static bool search_nested_keyrings(struct key *keyring,
|
||||
/* Check to see if this top-level keyring is what we are looking for
|
||||
* and whether it is valid or not.
|
||||
*/
|
||||
if (ctx->flags & KEYRING_SEARCH_LOOKUP_ITERATE ||
|
||||
if (ctx->match_data.lookup_type == KEYRING_SEARCH_LOOKUP_ITERATE ||
|
||||
keyring_compare_object(keyring, &ctx->index_key)) {
|
||||
ctx->skipped_ret = 2;
|
||||
ctx->flags |= KEYRING_SEARCH_DO_STATE_CHECK;
|
||||
@@ -885,16 +892,25 @@ key_ref_t keyring_search(key_ref_t keyring,
|
||||
.index_key.type = type,
|
||||
.index_key.description = description,
|
||||
.cred = current_cred(),
|
||||
.match = type->match,
|
||||
.match_data = description,
|
||||
.flags = (type->def_lookup_type |
|
||||
KEYRING_SEARCH_DO_STATE_CHECK),
|
||||
.match_data.cmp = key_default_cmp,
|
||||
.match_data.raw_data = description,
|
||||
.match_data.lookup_type = KEYRING_SEARCH_LOOKUP_DIRECT,
|
||||
.flags = KEYRING_SEARCH_DO_STATE_CHECK,
|
||||
};
|
||||
key_ref_t key;
|
||||
int ret;
|
||||
|
||||
if (!ctx.match)
|
||||
return ERR_PTR(-ENOKEY);
|
||||
if (type->match_preparse) {
|
||||
ret = type->match_preparse(&ctx.match_data);
|
||||
if (ret < 0)
|
||||
return ERR_PTR(ret);
|
||||
}
|
||||
|
||||
return keyring_search_aux(keyring, &ctx);
|
||||
key = keyring_search_aux(keyring, &ctx);
|
||||
|
||||
if (type->match_free)
|
||||
type->match_free(&ctx.match_data);
|
||||
return key;
|
||||
}
|
||||
EXPORT_SYMBOL(keyring_search);
|
||||
|
||||
@@ -1014,7 +1030,7 @@ static int keyring_detect_cycle_iterator(const void *object,
|
||||
|
||||
/* We might get a keyring with matching index-key that is nonetheless a
|
||||
* different keyring. */
|
||||
if (key != ctx->match_data)
|
||||
if (key != ctx->match_data.raw_data)
|
||||
return 0;
|
||||
|
||||
ctx->result = ERR_PTR(-EDEADLK);
|
||||
@@ -1031,14 +1047,14 @@ static int keyring_detect_cycle_iterator(const void *object,
|
||||
static int keyring_detect_cycle(struct key *A, struct key *B)
|
||||
{
|
||||
struct keyring_search_context ctx = {
|
||||
.index_key = A->index_key,
|
||||
.match_data = A,
|
||||
.iterator = keyring_detect_cycle_iterator,
|
||||
.flags = (KEYRING_SEARCH_LOOKUP_DIRECT |
|
||||
KEYRING_SEARCH_NO_STATE_CHECK |
|
||||
KEYRING_SEARCH_NO_UPDATE_TIME |
|
||||
KEYRING_SEARCH_NO_CHECK_PERM |
|
||||
KEYRING_SEARCH_DETECT_TOO_DEEP),
|
||||
.index_key = A->index_key,
|
||||
.match_data.raw_data = A,
|
||||
.match_data.lookup_type = KEYRING_SEARCH_LOOKUP_DIRECT,
|
||||
.iterator = keyring_detect_cycle_iterator,
|
||||
.flags = (KEYRING_SEARCH_NO_STATE_CHECK |
|
||||
KEYRING_SEARCH_NO_UPDATE_TIME |
|
||||
KEYRING_SEARCH_NO_CHECK_PERM |
|
||||
KEYRING_SEARCH_DETECT_TOO_DEEP),
|
||||
};
|
||||
|
||||
rcu_read_lock();
|
||||
|
||||
@@ -194,10 +194,10 @@ static int proc_keys_show(struct seq_file *m, void *v)
|
||||
.index_key.type = key->type,
|
||||
.index_key.description = key->description,
|
||||
.cred = current_cred(),
|
||||
.match = lookup_user_key_possessed,
|
||||
.match_data = key,
|
||||
.flags = (KEYRING_SEARCH_NO_STATE_CHECK |
|
||||
KEYRING_SEARCH_LOOKUP_DIRECT),
|
||||
.match_data.cmp = lookup_user_key_possessed,
|
||||
.match_data.raw_data = key,
|
||||
.match_data.lookup_type = KEYRING_SEARCH_LOOKUP_DIRECT,
|
||||
.flags = KEYRING_SEARCH_NO_STATE_CHECK,
|
||||
};
|
||||
|
||||
key_ref = make_key_ref(key, 0);
|
||||
|
||||
@@ -489,9 +489,10 @@ found:
|
||||
/*
|
||||
* See if the key we're looking at is the target key.
|
||||
*/
|
||||
int lookup_user_key_possessed(const struct key *key, const void *target)
|
||||
bool lookup_user_key_possessed(const struct key *key,
|
||||
const struct key_match_data *match_data)
|
||||
{
|
||||
return key == target;
|
||||
return key == match_data->raw_data;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -516,9 +517,9 @@ key_ref_t lookup_user_key(key_serial_t id, unsigned long lflags,
|
||||
key_perm_t perm)
|
||||
{
|
||||
struct keyring_search_context ctx = {
|
||||
.match = lookup_user_key_possessed,
|
||||
.flags = (KEYRING_SEARCH_NO_STATE_CHECK |
|
||||
KEYRING_SEARCH_LOOKUP_DIRECT),
|
||||
.match_data.cmp = lookup_user_key_possessed,
|
||||
.match_data.lookup_type = KEYRING_SEARCH_LOOKUP_DIRECT,
|
||||
.flags = KEYRING_SEARCH_NO_STATE_CHECK,
|
||||
};
|
||||
struct request_key_auth *rka;
|
||||
struct key *key;
|
||||
@@ -673,7 +674,7 @@ try_again:
|
||||
ctx.index_key.type = key->type;
|
||||
ctx.index_key.description = key->description;
|
||||
ctx.index_key.desc_len = strlen(key->description);
|
||||
ctx.match_data = key;
|
||||
ctx.match_data.raw_data = key;
|
||||
kdebug("check possessed");
|
||||
skey_ref = search_process_keyrings(&ctx);
|
||||
kdebug("possessed=%p", skey_ref);
|
||||
|
||||
@@ -531,9 +531,9 @@ struct key *request_key_and_link(struct key_type *type,
|
||||
.index_key.type = type,
|
||||
.index_key.description = description,
|
||||
.cred = current_cred(),
|
||||
.match = type->match,
|
||||
.match_data = description,
|
||||
.flags = KEYRING_SEARCH_LOOKUP_DIRECT,
|
||||
.match_data.cmp = key_default_cmp,
|
||||
.match_data.raw_data = description,
|
||||
.match_data.lookup_type = KEYRING_SEARCH_LOOKUP_DIRECT,
|
||||
};
|
||||
struct key *key;
|
||||
key_ref_t key_ref;
|
||||
@@ -543,6 +543,14 @@ struct key *request_key_and_link(struct key_type *type,
|
||||
ctx.index_key.type->name, ctx.index_key.description,
|
||||
callout_info, callout_len, aux, dest_keyring, flags);
|
||||
|
||||
if (type->match_preparse) {
|
||||
ret = type->match_preparse(&ctx.match_data);
|
||||
if (ret < 0) {
|
||||
key = ERR_PTR(ret);
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
|
||||
/* search all the process keyrings for a key */
|
||||
key_ref = search_process_keyrings(&ctx);
|
||||
|
||||
@@ -555,7 +563,7 @@ struct key *request_key_and_link(struct key_type *type,
|
||||
if (ret < 0) {
|
||||
key_put(key);
|
||||
key = ERR_PTR(ret);
|
||||
goto error;
|
||||
goto error_free;
|
||||
}
|
||||
}
|
||||
} else if (PTR_ERR(key_ref) != -EAGAIN) {
|
||||
@@ -565,12 +573,15 @@ struct key *request_key_and_link(struct key_type *type,
|
||||
* should consult userspace if we can */
|
||||
key = ERR_PTR(-ENOKEY);
|
||||
if (!callout_info)
|
||||
goto error;
|
||||
goto error_free;
|
||||
|
||||
key = construct_key_and_link(&ctx, callout_info, callout_len,
|
||||
aux, dest_keyring, flags);
|
||||
}
|
||||
|
||||
error_free:
|
||||
if (type->match_free)
|
||||
type->match_free(&ctx.match_data);
|
||||
error:
|
||||
kleave(" = %p", key);
|
||||
return key;
|
||||
|
||||
@@ -44,12 +44,12 @@ struct key_type key_type_request_key_auth = {
|
||||
.read = request_key_auth_read,
|
||||
};
|
||||
|
||||
int request_key_auth_preparse(struct key_preparsed_payload *prep)
|
||||
static int request_key_auth_preparse(struct key_preparsed_payload *prep)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void request_key_auth_free_preparse(struct key_preparsed_payload *prep)
|
||||
static void request_key_auth_free_preparse(struct key_preparsed_payload *prep)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -246,9 +246,9 @@ struct key *key_get_instantiation_authkey(key_serial_t target_id)
|
||||
.index_key.type = &key_type_request_key_auth,
|
||||
.index_key.description = description,
|
||||
.cred = current_cred(),
|
||||
.match = user_match,
|
||||
.match_data = description,
|
||||
.flags = KEYRING_SEARCH_LOOKUP_DIRECT,
|
||||
.match_data.cmp = key_default_cmp,
|
||||
.match_data.raw_data = description,
|
||||
.match_data.lookup_type = KEYRING_SEARCH_LOOKUP_DIRECT,
|
||||
};
|
||||
struct key *authkey;
|
||||
key_ref_t authkey_ref;
|
||||
|
||||
@@ -1096,7 +1096,6 @@ struct key_type key_type_trusted = {
|
||||
.name = "trusted",
|
||||
.instantiate = trusted_instantiate,
|
||||
.update = trusted_update,
|
||||
.match = user_match,
|
||||
.destroy = trusted_destroy,
|
||||
.describe = user_describe,
|
||||
.read = trusted_read,
|
||||
|
||||
@@ -26,12 +26,10 @@ static int logon_vet_description(const char *desc);
|
||||
*/
|
||||
struct key_type key_type_user = {
|
||||
.name = "user",
|
||||
.def_lookup_type = KEYRING_SEARCH_LOOKUP_DIRECT,
|
||||
.preparse = user_preparse,
|
||||
.free_preparse = user_free_preparse,
|
||||
.instantiate = generic_key_instantiate,
|
||||
.update = user_update,
|
||||
.match = user_match,
|
||||
.revoke = user_revoke,
|
||||
.destroy = user_destroy,
|
||||
.describe = user_describe,
|
||||
@@ -48,12 +46,10 @@ EXPORT_SYMBOL_GPL(key_type_user);
|
||||
*/
|
||||
struct key_type key_type_logon = {
|
||||
.name = "logon",
|
||||
.def_lookup_type = KEYRING_SEARCH_LOOKUP_DIRECT,
|
||||
.preparse = user_preparse,
|
||||
.free_preparse = user_free_preparse,
|
||||
.instantiate = generic_key_instantiate,
|
||||
.update = user_update,
|
||||
.match = user_match,
|
||||
.revoke = user_revoke,
|
||||
.destroy = user_destroy,
|
||||
.describe = user_describe,
|
||||
@@ -138,16 +134,6 @@ error:
|
||||
|
||||
EXPORT_SYMBOL_GPL(user_update);
|
||||
|
||||
/*
|
||||
* match users on their name
|
||||
*/
|
||||
int user_match(const struct key *key, const void *description)
|
||||
{
|
||||
return strcmp(key->description, description) == 0;
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL_GPL(user_match);
|
||||
|
||||
/*
|
||||
* dispose of the links from a revoked keyring
|
||||
* - called with the key sem write-locked
|
||||
|
||||
Reference in New Issue
Block a user