History

Merge tag 'keys-fixes-20171208' of git://git.kernel.org/pub/scm/linux/kernel/git/dhowells/linux-fs into keys-for-linus

Assorted fixes for keyrings, ASN.1, X.509 and PKCS#7.

James Morris committed 8 years ago

Commit 4ded3be2 parents f335195 54c1fb311 files · +101 −69Browse files

Unified · Split

11 files
  1. crypto/asymmetric_keys/pkcs7_parser.c +3 −1
  2. crypto/asymmetric_keys/pkcs7_trust.c +1 −1
  3. crypto/asymmetric_keys/pkcs7_verify.c +3 −6
  4. crypto/asymmetric_keys/public_key.c +5 −2
  5. crypto/asymmetric_keys/x509_cert_parser.c +2 −0
  6. crypto/asymmetric_keys/x509_public_key.c +2 −6
  7. lib/asn1_decoder.c +28 −21
  8. lib/oid_registry.c +10 −6
  9. security/keys/key.c +0 −1
  10. security/keys/keyctl.c +10 −14
  11. security/keys/request_key.c +37 −11
crypto/asymmetric_keys/pkcs7_parser.c+3−1
@@ -148,8 +148,10 @@ struct pkcs7_message *pkcs7_parse_message(const void *data, size_t datalen) · 147 unmodified lines
148 }148 }
149 149
150 ret = pkcs7_check_authattrs(ctx->msg);150 ret = pkcs7_check_authattrs(ctx->msg);
151 if (ret < 0)151 if (ret < 0) {
152 msg = ERR_PTR(ret);
152 goto out;153 goto out;
154 }
153 155
154 msg = ctx->msg;156 msg = ctx->msg;
155 ctx->msg = NULL;157 ctx->msg = NULL;
crypto/asymmetric_keys/pkcs7_trust.c+1−1
@@ -69,7 +69,7 @@ static int pkcs7_validate_trust_one(struct pkcs7_message *pkcs7, · 68 unmodified lines
69 /* Self-signed certificates form roots of their own, and if we69 /* Self-signed certificates form roots of their own, and if we
70 * don't know them, then we can't accept them.70 * don't know them, then we can't accept them.
71 */71 */
72 if (x509->next == x509) {72 if (x509->signer == x509) {
73 kleave(" = -ENOKEY [unknown self-signed]");73 kleave(" = -ENOKEY [unknown self-signed]");
74 return -ENOKEY;74 return -ENOKEY;
75 }75 }
crypto/asymmetric_keys/pkcs7_verify.c+3−6
@@ -59,11 +59,8 @@ static int pkcs7_digest(struct pkcs7_message *pkcs7, · 58 unmodified lines
59 desc->flags = CRYPTO_TFM_REQ_MAY_SLEEP;59 desc->flags = CRYPTO_TFM_REQ_MAY_SLEEP;
60 60
61 /* Digest the message [RFC2315 9.3] */61 /* Digest the message [RFC2315 9.3] */
62 ret = crypto_shash_init(desc);62 ret = crypto_shash_digest(desc, pkcs7->data, pkcs7->data_len,
63 if (ret < 0)63 sig->digest);
64 goto error;
65 ret = crypto_shash_finup(desc, pkcs7->data, pkcs7->data_len,
66 sig->digest);
67 if (ret < 0)64 if (ret < 0)
68 goto error;65 goto error;
69 pr_devel("MsgDigest = [%*ph]\n", 8, sig->digest);66 pr_devel("MsgDigest = [%*ph]\n", 8, sig->digest);
@@ -150,7 +147,7 @@ static int pkcs7_find_key(struct pkcs7_message *pkcs7, · 80 unmodified lines
150 pr_devel("Sig %u: Found cert serial match X.509[%u]\n",147 pr_devel("Sig %u: Found cert serial match X.509[%u]\n",
151 sinfo->index, certix);148 sinfo->index, certix);
152 149
153 if (x509->pub->pkey_algo != sinfo->sig->pkey_algo) {150 if (strcmp(x509->pub->pkey_algo, sinfo->sig->pkey_algo) != 0) {
154 pr_warn("Sig %u: X.509 algo and PKCS#7 sig algo don't match\n",151 pr_warn("Sig %u: X.509 algo and PKCS#7 sig algo don't match\n",
155 sinfo->index);152 sinfo->index);
156 continue;153 continue;
crypto/asymmetric_keys/public_key.c+5−2
@@ -73,7 +73,7 @@ int public_key_verify_signature(const struct public_key *pkey, · 72 unmodified lines
73 char alg_name_buf[CRYPTO_MAX_ALG_NAME];73 char alg_name_buf[CRYPTO_MAX_ALG_NAME];
74 void *output;74 void *output;
75 unsigned int outlen;75 unsigned int outlen;
76 int ret = -ENOMEM;76 int ret;
77 77
78 pr_devel("==>%s()\n", __func__);78 pr_devel("==>%s()\n", __func__);
79 79
@@ -99,6 +99,7 @@ int public_key_verify_signature(const struct public_key *pkey, · 19 unmodified lines
99 if (IS_ERR(tfm))99 if (IS_ERR(tfm))
100 return PTR_ERR(tfm);100 return PTR_ERR(tfm);
101 101
102 ret = -ENOMEM;
102 req = akcipher_request_alloc(tfm, GFP_KERNEL);103 req = akcipher_request_alloc(tfm, GFP_KERNEL);
103 if (!req)104 if (!req)
104 goto error_free_tfm;105 goto error_free_tfm;
@@ -127,7 +128,7 @@ int public_key_verify_signature(const struct public_key *pkey, · 22 unmodified lines
127 * signature and returns that to us.128 * signature and returns that to us.
128 */129 */
129 ret = crypto_wait_req(crypto_akcipher_verify(req), &cwait);130 ret = crypto_wait_req(crypto_akcipher_verify(req), &cwait);
130 if (ret < 0)131 if (ret)
131 goto out_free_output;132 goto out_free_output;
132 133
133 /* Do the actual verification step. */134 /* Do the actual verification step. */
@@ -142,6 +143,8 @@ error_free_req: · 8 unmodified lines
142error_free_tfm:143error_free_tfm:
143 crypto_free_akcipher(tfm);144 crypto_free_akcipher(tfm);
144 pr_devel("<==%s() = %d\n", __func__, ret);145 pr_devel("<==%s() = %d\n", __func__, ret);
146 if (WARN_ON_ONCE(ret > 0))
147 ret = -EINVAL;
145 return ret;148 return ret;
146}149}
147EXPORT_SYMBOL_GPL(public_key_verify_signature);150EXPORT_SYMBOL_GPL(public_key_verify_signature);
crypto/asymmetric_keys/x509_cert_parser.c+2−0
@@ -409,6 +409,8 @@ int x509_extract_key_data(void *context, size_t hdrlen, · 408 unmodified lines
409 ctx->cert->pub->pkey_algo = "rsa";409 ctx->cert->pub->pkey_algo = "rsa";
410 410
411 /* Discard the BIT STRING metadata */411 /* Discard the BIT STRING metadata */
412 if (vlen < 1 || *(const u8 *)value != 0)
413 return -EBADMSG;
412 ctx->key = value + 1;414 ctx->key = value + 1;
413 ctx->key_size = vlen - 1;415 ctx->key_size = vlen - 1;
414 return 0;416 return 0;
crypto/asymmetric_keys/x509_public_key.c+2−6
@@ -79,11 +79,7 @@ int x509_get_sig_params(struct x509_certificate *cert) · 78 unmodified lines
79 desc->tfm = tfm;79 desc->tfm = tfm;
80 desc->flags = CRYPTO_TFM_REQ_MAY_SLEEP;80 desc->flags = CRYPTO_TFM_REQ_MAY_SLEEP;
81 81
82 ret = crypto_shash_init(desc);82 ret = crypto_shash_digest(desc, cert->tbs, cert->tbs_size, sig->digest);
83 if (ret < 0)
84 goto error_2;
85 might_sleep();
86 ret = crypto_shash_finup(desc, cert->tbs, cert->tbs_size, sig->digest);
87 if (ret < 0)83 if (ret < 0)
88 goto error_2;84 goto error_2;
89 85
@@ -135,7 +131,7 @@ int x509_check_for_self_signed(struct x509_certificate *cert) · 45 unmodified lines
135 }131 }
136 132
137 ret = -EKEYREJECTED;133 ret = -EKEYREJECTED;
138 if (cert->pub->pkey_algo != cert->sig->pkey_algo)134 if (strcmp(cert->pub->pkey_algo, cert->sig->pkey_algo) != 0)
139 goto out;135 goto out;
140 136
141 ret = public_key_verify_signature(cert->pub, cert->sig);137 ret = public_key_verify_signature(cert->pub, cert->sig);
lib/asn1_decoder.c+28−21
@@ -313,42 +313,47 @@ next_op: · 312 unmodified lines
313 313
314 /* Decide how to handle the operation */314 /* Decide how to handle the operation */
315 switch (op) {315 switch (op) {
316 case ASN1_OP_MATCH_ANY_ACT:
317 case ASN1_OP_MATCH_ANY_ACT_OR_SKIP:
318 case ASN1_OP_COND_MATCH_ANY_ACT:
319 case ASN1_OP_COND_MATCH_ANY_ACT_OR_SKIP:
320 ret = actions[machine[pc + 1]](context, hdr, tag, data + dp, len);
321 if (ret < 0)
322 return ret;
323 goto skip_data;
324
325 case ASN1_OP_MATCH_ACT:
326 case ASN1_OP_MATCH_ACT_OR_SKIP:
327 case ASN1_OP_COND_MATCH_ACT_OR_SKIP:
328 ret = actions[machine[pc + 2]](context, hdr, tag, data + dp, len);
329 if (ret < 0)
330 return ret;
331 goto skip_data;
332
333 case ASN1_OP_MATCH:316 case ASN1_OP_MATCH:
334 case ASN1_OP_MATCH_OR_SKIP:317 case ASN1_OP_MATCH_OR_SKIP:
318 case ASN1_OP_MATCH_ACT:
319 case ASN1_OP_MATCH_ACT_OR_SKIP:
335 case ASN1_OP_MATCH_ANY:320 case ASN1_OP_MATCH_ANY:
336 case ASN1_OP_MATCH_ANY_OR_SKIP:321 case ASN1_OP_MATCH_ANY_OR_SKIP:
322 case ASN1_OP_MATCH_ANY_ACT:
323 case ASN1_OP_MATCH_ANY_ACT_OR_SKIP:
337 case ASN1_OP_COND_MATCH_OR_SKIP:324 case ASN1_OP_COND_MATCH_OR_SKIP:
325 case ASN1_OP_COND_MATCH_ACT_OR_SKIP:
338 case ASN1_OP_COND_MATCH_ANY:326 case ASN1_OP_COND_MATCH_ANY:
339 case ASN1_OP_COND_MATCH_ANY_OR_SKIP:327 case ASN1_OP_COND_MATCH_ANY_OR_SKIP:
340 skip_data:328 case ASN1_OP_COND_MATCH_ANY_ACT:
329 case ASN1_OP_COND_MATCH_ANY_ACT_OR_SKIP:
330
341 if (!(flags & FLAG_CONS)) {331 if (!(flags & FLAG_CONS)) {
342 if (flags & FLAG_INDEFINITE_LENGTH) {332 if (flags & FLAG_INDEFINITE_LENGTH) {
333 size_t tmp = dp;
334
343 ret = asn1_find_indefinite_length(335 ret = asn1_find_indefinite_length(
344 data, datalen, &dp, &len, &errmsg);336 data, datalen, &tmp, &len, &errmsg);
345 if (ret < 0)337 if (ret < 0)
346 goto error;338 goto error;
347 } else {
348 dp += len;
349 }339 }
350 pr_debug("- LEAF: %zu\n", len);340 pr_debug("- LEAF: %zu\n", len);
351 }341 }
342
343 if (op & ASN1_OP_MATCH__ACT) {
344 unsigned char act;
345
346 if (op & ASN1_OP_MATCH__ANY)
347 act = machine[pc + 1];
348 else
349 act = machine[pc + 2];
350 ret = actions[act](context, hdr, tag, data + dp, len);
351 if (ret < 0)
352 return ret;
353 }
354
355 if (!(flags & FLAG_CONS))
356 dp += len;
352 pc += asn1_op_lengths[op];357 pc += asn1_op_lengths[op];
353 goto next_op;358 goto next_op;
354 359
@@ -434,6 +439,8 @@ next_op: · 79 unmodified lines
434 else439 else
435 act = machine[pc + 1];440 act = machine[pc + 1];
436 ret = actions[act](context, hdr, 0, data + tdp, len);441 ret = actions[act](context, hdr, 0, data + tdp, len);
442 if (ret < 0)
443 return ret;
437 }444 }
438 pc += asn1_op_lengths[op];445 pc += asn1_op_lengths[op];
439 goto next_op;446 goto next_op;
lib/oid_registry.c+10−6
@@ -116,14 +116,14 @@ int sprint_oid(const void *data, size_t datasize, char *buffer, size_t bufsize) · 115 unmodified lines
116 int count;116 int count;
117 117
118 if (v >= end)118 if (v >= end)
119 return -EBADMSG;119 goto bad;
120 120
121 n = *v++;121 n = *v++;
122 ret = count = snprintf(buffer, bufsize, "%u.%u", n / 40, n % 40);122 ret = count = snprintf(buffer, bufsize, "%u.%u", n / 40, n % 40);
123 if (count >= bufsize)
124 return -ENOBUFS;
123 buffer += count;125 buffer += count;
124 bufsize -= count;126 bufsize -= count;
125 if (bufsize == 0)
126 return -ENOBUFS;
127 127
128 while (v < end) {128 while (v < end) {
129 num = 0;129 num = 0;
@@ -134,20 +134,24 @@ int sprint_oid(const void *data, size_t datasize, char *buffer, size_t bufsize) · 4 unmodified lines
134 num = n & 0x7f;134 num = n & 0x7f;
135 do {135 do {
136 if (v >= end)136 if (v >= end)
137 return -EBADMSG;137 goto bad;
138 n = *v++;138 n = *v++;
139 num <<= 7;139 num <<= 7;
140 num |= n & 0x7f;140 num |= n & 0x7f;
141 } while (n & 0x80);141 } while (n & 0x80);
142 }142 }
143 ret += count = snprintf(buffer, bufsize, ".%lu", num);143 ret += count = snprintf(buffer, bufsize, ".%lu", num);
144 buffer += count;144 if (count >= bufsize)
145 if (bufsize <= count)
146 return -ENOBUFS;145 return -ENOBUFS;
146 buffer += count;
147 bufsize -= count;147 bufsize -= count;
148 }148 }
149 149
150 return ret;150 return ret;
151
152bad:
153 snprintf(buffer, bufsize, "(bad)");
154 return -EBADMSG;
151}155}
152EXPORT_SYMBOL_GPL(sprint_oid);156EXPORT_SYMBOL_GPL(sprint_oid);
153 157
security/keys/key.c+0−1
@@ -833,7 +833,6 @@ key_ref_t key_create_or_update(key_ref_t keyring_ref, · 832 unmodified lines
833 833
834 key_check(keyring);834 key_check(keyring);
835 835
836 key_ref = ERR_PTR(-EPERM);
837 if (!(flags & KEY_ALLOC_BYPASS_RESTRICTION))836 if (!(flags & KEY_ALLOC_BYPASS_RESTRICTION))
838 restrict_link = keyring->restrict_link;837 restrict_link = keyring->restrict_link;
839 838
security/keys/keyctl.c+10−14
@@ -1588,9 +1588,8 @@ error_keyring: · 1587 unmodified lines
1588 * The caller must have Setattr permission to change keyring restrictions.1588 * The caller must have Setattr permission to change keyring restrictions.
1589 *1589 *
1590 * The requested type name may be a NULL pointer to reject all attempts1590 * The requested type name may be a NULL pointer to reject all attempts
1591 * to link to the keyring. If _type is non-NULL, _restriction can be1591 * to link to the keyring. In this case, _restriction must also be NULL.
1592 * NULL or a pointer to a string describing the restriction. If _type is1592 * Otherwise, both _type and _restriction must be non-NULL.
1593 * NULL, _restriction must also be NULL.
1594 *1593 *
1595 * Returns 0 if successful.1594 * Returns 0 if successful.
1596 */1595 */
@@ -1598,7 +1597,6 @@ long keyctl_restrict_keyring(key_serial_t id, const char __user *_type, · 1 unmodified line
1598 const char __user *_restriction)1597 const char __user *_restriction)
1599{1598{
1600 key_ref_t key_ref;1599 key_ref_t key_ref;
1601 bool link_reject = !_type;
1602 char type[32];1600 char type[32];
1603 char *restriction = NULL;1601 char *restriction = NULL;
1604 long ret;1602 long ret;
@@ -1607,31 +1605,29 @@ long keyctl_restrict_keyring(key_serial_t id, const char __user *_type, · 2 unmodified lines
1607 if (IS_ERR(key_ref))1605 if (IS_ERR(key_ref))
1608 return PTR_ERR(key_ref);1606 return PTR_ERR(key_ref);
1609 1607
1608 ret = -EINVAL;
1610 if (_type) {1609 if (_type) {
1611 ret = key_get_type_from_user(type, _type, sizeof(type));1610 if (!_restriction)
1612 if (ret < 0)
1613 goto error;1611 goto error;
1614 }
1615 1612
1616 if (_restriction) {1613 ret = key_get_type_from_user(type, _type, sizeof(type));
1617 if (!_type) {1614 if (ret < 0)
1618 ret = -EINVAL;
1619 goto error;1615 goto error;
1620 }
1621 1616
1622 restriction = strndup_user(_restriction, PAGE_SIZE);1617 restriction = strndup_user(_restriction, PAGE_SIZE);
1623 if (IS_ERR(restriction)) {1618 if (IS_ERR(restriction)) {
1624 ret = PTR_ERR(restriction);1619 ret = PTR_ERR(restriction);
1625 goto error;1620 goto error;
1626 }1621 }
1622 } else {
1623 if (_restriction)
1624 goto error;
1627 }1625 }
1628 1626
1629 ret = keyring_restrict(key_ref, link_reject ? NULL : type, restriction);1627 ret = keyring_restrict(key_ref, _type ? type : NULL, restriction);
1630 kfree(restriction);1628 kfree(restriction);
1631
1632error:1629error:
1633 key_ref_put(key_ref);1630 key_ref_put(key_ref);
1634
1635 return ret;1631 return ret;
1636}1632}
1637 1633
security/keys/request_key.c+37−11
@@ -251,11 +251,12 @@ static int construct_key(struct key *key, const void *callout_info, · 250 unmodified lines
251 * The keyring selected is returned with an extra reference upon it which the251 * The keyring selected is returned with an extra reference upon it which the
252 * caller must release.252 * caller must release.
253 */253 */
254static void construct_get_dest_keyring(struct key **_dest_keyring)254static int construct_get_dest_keyring(struct key **_dest_keyring)
255{255{
256 struct request_key_auth *rka;256 struct request_key_auth *rka;
257 const struct cred *cred = current_cred();257 const struct cred *cred = current_cred();
258 struct key *dest_keyring = *_dest_keyring, *authkey;258 struct key *dest_keyring = *_dest_keyring, *authkey;
259 int ret;
259 260
260 kenter("%p", dest_keyring);261 kenter("%p", dest_keyring);
261 262
@@ -264,6 +265,8 @@ static void construct_get_dest_keyring(struct key **_dest_keyring) · 2 unmodified lines
264 /* the caller supplied one */265 /* the caller supplied one */
265 key_get(dest_keyring);266 key_get(dest_keyring);
266 } else {267 } else {
268 bool do_perm_check = true;
269
267 /* use a default keyring; falling through the cases until we270 /* use a default keyring; falling through the cases until we
268 * find one that we actually have */271 * find one that we actually have */
269 switch (cred->jit_keyring) {272 switch (cred->jit_keyring) {
@@ -278,8 +281,10 @@ static void construct_get_dest_keyring(struct key **_dest_keyring) · 8 unmodified lines
278 dest_keyring =281 dest_keyring =
279 key_get(rka->dest_keyring);282 key_get(rka->dest_keyring);
280 up_read(&authkey->sem);283 up_read(&authkey->sem);
281 if (dest_keyring)284 if (dest_keyring) {
285 do_perm_check = false;
282 break;286 break;
287 }
283 }288 }
284 289
285 case KEY_REQKEY_DEFL_THREAD_KEYRING:290 case KEY_REQKEY_DEFL_THREAD_KEYRING:
@@ -314,11 +319,29 @@ static void construct_get_dest_keyring(struct key **_dest_keyring) · 28 unmodified lines
314 default:319 default:
315 BUG();320 BUG();
316 }321 }
322
323 /*
324 * Require Write permission on the keyring. This is essential
325 * because the default keyring may be the session keyring, and
326 * joining a keyring only requires Search permission.
327 *
328 * However, this check is skipped for the "requestor keyring" so
329 * that /sbin/request-key can itself use request_key() to add
330 * keys to the original requestor's destination keyring.
331 */
332 if (dest_keyring && do_perm_check) {
333 ret = key_permission(make_key_ref(dest_keyring, 1),
334 KEY_NEED_WRITE);
335 if (ret) {
336 key_put(dest_keyring);
337 return ret;
338 }
339 }
317 }340 }
318 341
319 *_dest_keyring = dest_keyring;342 *_dest_keyring = dest_keyring;
320 kleave(" [dk %d]", key_serial(dest_keyring));343 kleave(" [dk %d]", key_serial(dest_keyring));
321 return;344 return 0;
322}345}
323 346
324/*347/*
@@ -444,11 +467,15 @@ static struct key *construct_key_and_link(struct keyring_search_context *ctx, · 119 unmodified lines
444 if (ctx->index_key.type == &key_type_keyring)467 if (ctx->index_key.type == &key_type_keyring)
445 return ERR_PTR(-EPERM);468 return ERR_PTR(-EPERM);
446 469
447 user = key_user_lookup(current_fsuid());470 ret = construct_get_dest_keyring(&dest_keyring);
448 if (!user)471 if (ret)
449 return ERR_PTR(-ENOMEM);472 goto error;
450 473
451 construct_get_dest_keyring(&dest_keyring);474 user = key_user_lookup(current_fsuid());
475 if (!user) {
476 ret = -ENOMEM;
477 goto error_put_dest_keyring;
478 }
452 479
453 ret = construct_alloc_key(ctx, dest_keyring, flags, user, &key);480 ret = construct_alloc_key(ctx, dest_keyring, flags, user, &key);
454 key_user_put(user);481 key_user_put(user);
@@ -463,7 +490,7 @@ static struct key *construct_key_and_link(struct keyring_search_context *ctx, · 8 unmodified lines
463 } else if (ret == -EINPROGRESS) {490 } else if (ret == -EINPROGRESS) {
464 ret = 0;491 ret = 0;
465 } else {492 } else {
466 goto couldnt_alloc_key;493 goto error_put_dest_keyring;
467 }494 }
468 495
469 key_put(dest_keyring);496 key_put(dest_keyring);
@@ -473,8 +500,9 @@ static struct key *construct_key_and_link(struct keyring_search_context *ctx, · 3 unmodified lines
473construction_failed:500construction_failed:
474 key_negate_and_link(key, key_negative_timeout, NULL, NULL);501 key_negate_and_link(key, key_negative_timeout, NULL, NULL);
475 key_put(key);502 key_put(key);
476couldnt_alloc_key:503error_put_dest_keyring:
477 key_put(dest_keyring);504 key_put(dest_keyring);
505error:
478 kleave(" = %d", ret);506 kleave(" = %d", ret);
479 return ERR_PTR(ret);507 return ERR_PTR(ret);
480}508}
@@ -546,9 +574,7 @@ struct key *request_key_and_link(struct key_type *type, · 65 unmodified lines
546 if (!IS_ERR(key_ref)) {574 if (!IS_ERR(key_ref)) {
547 key = key_ref_to_ptr(key_ref);575 key = key_ref_to_ptr(key_ref);
548 if (dest_keyring) {576 if (dest_keyring) {
549 construct_get_dest_keyring(&dest_keyring);
550 ret = key_link(dest_keyring, key);577 ret = key_link(dest_keyring, key);
551 key_put(dest_keyring);
552 if (ret < 0) {578 if (ret < 0) {
553 key_put(key);579 key_put(key);
554 key = ERR_PTR(ret);580 key = ERR_PTR(ret);