Loading security/keys/internal.h +1 −0 Original line number Diff line number Diff line Loading @@ -117,6 +117,7 @@ struct keyring_search_context { #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 */ #define KEYRING_SEARCH_SKIP_EXPIRED 0x0020 /* Ignore expired keys (intention to replace) */ int (*iterator)(const void *object, void *iterator_data); Loading security/keys/keyctl.c +26 −30 Original line number Diff line number Diff line Loading @@ -26,6 +26,8 @@ #include <asm/uaccess.h> #include "internal.h" #define KEY_MAX_DESC_SIZE 4096 static int key_get_type_from_user(char *type, const char __user *_type, unsigned len) Loading Loading @@ -78,7 +80,7 @@ SYSCALL_DEFINE5(add_key, const char __user *, _type, description = NULL; if (_description) { description = strndup_user(_description, PAGE_SIZE); description = strndup_user(_description, KEY_MAX_DESC_SIZE); if (IS_ERR(description)) { ret = PTR_ERR(description); goto error; Loading Loading @@ -177,7 +179,7 @@ SYSCALL_DEFINE4(request_key, const char __user *, _type, goto error; /* pull the description into kernel space */ description = strndup_user(_description, PAGE_SIZE); description = strndup_user(_description, KEY_MAX_DESC_SIZE); if (IS_ERR(description)) { ret = PTR_ERR(description); goto error; Loading Loading @@ -287,7 +289,7 @@ long keyctl_join_session_keyring(const char __user *_name) /* fetch the name from userspace */ name = NULL; if (_name) { name = strndup_user(_name, PAGE_SIZE); name = strndup_user(_name, KEY_MAX_DESC_SIZE); if (IS_ERR(name)) { ret = PTR_ERR(name); goto error; Loading Loading @@ -562,8 +564,9 @@ long keyctl_describe_key(key_serial_t keyid, { struct key *key, *instkey; key_ref_t key_ref; char *tmpbuf; char *infobuf; long ret; int desclen, infolen; key_ref = lookup_user_key(keyid, KEY_LOOKUP_PARTIAL, KEY_NEED_VIEW); if (IS_ERR(key_ref)) { Loading @@ -586,38 +589,31 @@ long keyctl_describe_key(key_serial_t keyid, } okay: /* calculate how much description we're going to return */ ret = -ENOMEM; tmpbuf = kmalloc(PAGE_SIZE, GFP_KERNEL); if (!tmpbuf) goto error2; key = key_ref_to_ptr(key_ref); desclen = strlen(key->description); ret = snprintf(tmpbuf, PAGE_SIZE - 1, "%s;%d;%d;%08x;%s", /* calculate how much information we're going to return */ ret = -ENOMEM; infobuf = kasprintf(GFP_KERNEL, "%s;%d;%d;%08x;", key->type->name, from_kuid_munged(current_user_ns(), key->uid), from_kgid_munged(current_user_ns(), key->gid), key->perm, key->description ?: ""); /* include a NUL char at the end of the data */ if (ret > PAGE_SIZE - 1) ret = PAGE_SIZE - 1; tmpbuf[ret] = 0; ret++; key->perm); if (!infobuf) goto error2; infolen = strlen(infobuf); ret = infolen + desclen + 1; /* consider returning the data */ if (buffer && buflen > 0) { if (buflen > ret) buflen = ret; if (copy_to_user(buffer, tmpbuf, buflen) != 0) if (buffer && buflen >= ret) { if (copy_to_user(buffer, infobuf, infolen) != 0 || copy_to_user(buffer + infolen, key->description, desclen + 1) != 0) ret = -EFAULT; } kfree(tmpbuf); kfree(infobuf); error2: key_ref_put(key_ref); error: Loading Loading @@ -649,7 +645,7 @@ long keyctl_keyring_search(key_serial_t ringid, if (ret < 0) goto error; description = strndup_user(_description, PAGE_SIZE); description = strndup_user(_description, KEY_MAX_DESC_SIZE); if (IS_ERR(description)) { ret = PTR_ERR(description); goto error; Loading security/keys/keyring.c +6 −4 Original line number Diff line number Diff line Loading @@ -546,6 +546,7 @@ static int keyring_search_iterator(const void *object, void *iterator_data) } if (key->expiry && ctx->now.tv_sec >= key->expiry) { if (!(ctx->flags & KEYRING_SEARCH_SKIP_EXPIRED)) ctx->result = ERR_PTR(-EKEYEXPIRED); kleave(" = %d [expire]", ctx->skipped_ret); goto skipped; Loading Loading @@ -628,6 +629,10 @@ static bool search_nested_keyrings(struct key *keyring, ctx->index_key.type->name, ctx->index_key.description); #define STATE_CHECKS (KEYRING_SEARCH_NO_STATE_CHECK | KEYRING_SEARCH_DO_STATE_CHECK) BUG_ON((ctx->flags & STATE_CHECKS) == 0 || (ctx->flags & STATE_CHECKS) == STATE_CHECKS); if (ctx->index_key.description) ctx->index_key.desc_len = strlen(ctx->index_key.description); Loading @@ -637,7 +642,6 @@ static bool search_nested_keyrings(struct key *keyring, 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; switch (ctx->iterator(keyring_key_to_ptr(keyring), ctx)) { case 1: goto found; Loading @@ -649,8 +653,6 @@ static bool search_nested_keyrings(struct key *keyring, } ctx->skipped_ret = 0; if (ctx->flags & KEYRING_SEARCH_NO_STATE_CHECK) ctx->flags &= ~KEYRING_SEARCH_DO_STATE_CHECK; /* Start processing a new keyring */ descend_to_keyring: Loading security/keys/request_key.c +2 −0 Original line number Diff line number Diff line Loading @@ -516,6 +516,8 @@ struct key *request_key_and_link(struct key_type *type, .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 | KEYRING_SEARCH_SKIP_EXPIRED), }; struct key *key; key_ref_t key_ref; Loading security/keys/request_key_auth.c +1 −0 Original line number Diff line number Diff line Loading @@ -249,6 +249,7 @@ struct key *key_get_instantiation_authkey(key_serial_t target_id) .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, }; struct key *authkey; key_ref_t authkey_ref; Loading Loading
security/keys/internal.h +1 −0 Original line number Diff line number Diff line Loading @@ -117,6 +117,7 @@ struct keyring_search_context { #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 */ #define KEYRING_SEARCH_SKIP_EXPIRED 0x0020 /* Ignore expired keys (intention to replace) */ int (*iterator)(const void *object, void *iterator_data); Loading
security/keys/keyctl.c +26 −30 Original line number Diff line number Diff line Loading @@ -26,6 +26,8 @@ #include <asm/uaccess.h> #include "internal.h" #define KEY_MAX_DESC_SIZE 4096 static int key_get_type_from_user(char *type, const char __user *_type, unsigned len) Loading Loading @@ -78,7 +80,7 @@ SYSCALL_DEFINE5(add_key, const char __user *, _type, description = NULL; if (_description) { description = strndup_user(_description, PAGE_SIZE); description = strndup_user(_description, KEY_MAX_DESC_SIZE); if (IS_ERR(description)) { ret = PTR_ERR(description); goto error; Loading Loading @@ -177,7 +179,7 @@ SYSCALL_DEFINE4(request_key, const char __user *, _type, goto error; /* pull the description into kernel space */ description = strndup_user(_description, PAGE_SIZE); description = strndup_user(_description, KEY_MAX_DESC_SIZE); if (IS_ERR(description)) { ret = PTR_ERR(description); goto error; Loading Loading @@ -287,7 +289,7 @@ long keyctl_join_session_keyring(const char __user *_name) /* fetch the name from userspace */ name = NULL; if (_name) { name = strndup_user(_name, PAGE_SIZE); name = strndup_user(_name, KEY_MAX_DESC_SIZE); if (IS_ERR(name)) { ret = PTR_ERR(name); goto error; Loading Loading @@ -562,8 +564,9 @@ long keyctl_describe_key(key_serial_t keyid, { struct key *key, *instkey; key_ref_t key_ref; char *tmpbuf; char *infobuf; long ret; int desclen, infolen; key_ref = lookup_user_key(keyid, KEY_LOOKUP_PARTIAL, KEY_NEED_VIEW); if (IS_ERR(key_ref)) { Loading @@ -586,38 +589,31 @@ long keyctl_describe_key(key_serial_t keyid, } okay: /* calculate how much description we're going to return */ ret = -ENOMEM; tmpbuf = kmalloc(PAGE_SIZE, GFP_KERNEL); if (!tmpbuf) goto error2; key = key_ref_to_ptr(key_ref); desclen = strlen(key->description); ret = snprintf(tmpbuf, PAGE_SIZE - 1, "%s;%d;%d;%08x;%s", /* calculate how much information we're going to return */ ret = -ENOMEM; infobuf = kasprintf(GFP_KERNEL, "%s;%d;%d;%08x;", key->type->name, from_kuid_munged(current_user_ns(), key->uid), from_kgid_munged(current_user_ns(), key->gid), key->perm, key->description ?: ""); /* include a NUL char at the end of the data */ if (ret > PAGE_SIZE - 1) ret = PAGE_SIZE - 1; tmpbuf[ret] = 0; ret++; key->perm); if (!infobuf) goto error2; infolen = strlen(infobuf); ret = infolen + desclen + 1; /* consider returning the data */ if (buffer && buflen > 0) { if (buflen > ret) buflen = ret; if (copy_to_user(buffer, tmpbuf, buflen) != 0) if (buffer && buflen >= ret) { if (copy_to_user(buffer, infobuf, infolen) != 0 || copy_to_user(buffer + infolen, key->description, desclen + 1) != 0) ret = -EFAULT; } kfree(tmpbuf); kfree(infobuf); error2: key_ref_put(key_ref); error: Loading Loading @@ -649,7 +645,7 @@ long keyctl_keyring_search(key_serial_t ringid, if (ret < 0) goto error; description = strndup_user(_description, PAGE_SIZE); description = strndup_user(_description, KEY_MAX_DESC_SIZE); if (IS_ERR(description)) { ret = PTR_ERR(description); goto error; Loading
security/keys/keyring.c +6 −4 Original line number Diff line number Diff line Loading @@ -546,6 +546,7 @@ static int keyring_search_iterator(const void *object, void *iterator_data) } if (key->expiry && ctx->now.tv_sec >= key->expiry) { if (!(ctx->flags & KEYRING_SEARCH_SKIP_EXPIRED)) ctx->result = ERR_PTR(-EKEYEXPIRED); kleave(" = %d [expire]", ctx->skipped_ret); goto skipped; Loading Loading @@ -628,6 +629,10 @@ static bool search_nested_keyrings(struct key *keyring, ctx->index_key.type->name, ctx->index_key.description); #define STATE_CHECKS (KEYRING_SEARCH_NO_STATE_CHECK | KEYRING_SEARCH_DO_STATE_CHECK) BUG_ON((ctx->flags & STATE_CHECKS) == 0 || (ctx->flags & STATE_CHECKS) == STATE_CHECKS); if (ctx->index_key.description) ctx->index_key.desc_len = strlen(ctx->index_key.description); Loading @@ -637,7 +642,6 @@ static bool search_nested_keyrings(struct key *keyring, 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; switch (ctx->iterator(keyring_key_to_ptr(keyring), ctx)) { case 1: goto found; Loading @@ -649,8 +653,6 @@ static bool search_nested_keyrings(struct key *keyring, } ctx->skipped_ret = 0; if (ctx->flags & KEYRING_SEARCH_NO_STATE_CHECK) ctx->flags &= ~KEYRING_SEARCH_DO_STATE_CHECK; /* Start processing a new keyring */ descend_to_keyring: Loading
security/keys/request_key.c +2 −0 Original line number Diff line number Diff line Loading @@ -516,6 +516,8 @@ struct key *request_key_and_link(struct key_type *type, .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 | KEYRING_SEARCH_SKIP_EXPIRED), }; struct key *key; key_ref_t key_ref; Loading
security/keys/request_key_auth.c +1 −0 Original line number Diff line number Diff line Loading @@ -249,6 +249,7 @@ struct key *key_get_instantiation_authkey(key_serial_t target_id) .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, }; struct key *authkey; key_ref_t authkey_ref; Loading