Skip to content

Commit 4ded3be

Browse files
author
James Morris
committed
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.
2 parents f335195 + 54c1fb3 commit 4ded3be

File tree

11 files changed

+101
-69
lines changed

11 files changed

+101
-69
lines changed

crypto/asymmetric_keys/pkcs7_parser.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -148,8 +148,10 @@ struct pkcs7_message *pkcs7_parse_message(const void *data, size_t datalen)
148148
}
149149

150150
ret = pkcs7_check_authattrs(ctx->msg);
151-
if (ret < 0)
151+
if (ret < 0) {
152+
msg = ERR_PTR(ret);
152153
goto out;
154+
}
153155

154156
msg = ctx->msg;
155157
ctx->msg = NULL;

crypto/asymmetric_keys/pkcs7_trust.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ static int pkcs7_validate_trust_one(struct pkcs7_message *pkcs7,
6969
/* Self-signed certificates form roots of their own, and if we
7070
* don't know them, then we can't accept them.
7171
*/
72-
if (x509->next == x509) {
72+
if (x509->signer == x509) {
7373
kleave(" = -ENOKEY [unknown self-signed]");
7474
return -ENOKEY;
7575
}

crypto/asymmetric_keys/pkcs7_verify.c

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -59,11 +59,8 @@ static int pkcs7_digest(struct pkcs7_message *pkcs7,
5959
desc->flags = CRYPTO_TFM_REQ_MAY_SLEEP;
6060

6161
/* Digest the message [RFC2315 9.3] */
62-
ret = crypto_shash_init(desc);
63-
if (ret < 0)
64-
goto error;
65-
ret = crypto_shash_finup(desc, pkcs7->data, pkcs7->data_len,
66-
sig->digest);
62+
ret = crypto_shash_digest(desc, pkcs7->data, pkcs7->data_len,
63+
sig->digest);
6764
if (ret < 0)
6865
goto error;
6966
pr_devel("MsgDigest = [%*ph]\n", 8, sig->digest);
@@ -150,7 +147,7 @@ static int pkcs7_find_key(struct pkcs7_message *pkcs7,
150147
pr_devel("Sig %u: Found cert serial match X.509[%u]\n",
151148
sinfo->index, certix);
152149

153-
if (x509->pub->pkey_algo != sinfo->sig->pkey_algo) {
150+
if (strcmp(x509->pub->pkey_algo, sinfo->sig->pkey_algo) != 0) {
154151
pr_warn("Sig %u: X.509 algo and PKCS#7 sig algo don't match\n",
155152
sinfo->index);
156153
continue;

crypto/asymmetric_keys/public_key.c

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ int public_key_verify_signature(const struct public_key *pkey,
7373
char alg_name_buf[CRYPTO_MAX_ALG_NAME];
7474
void *output;
7575
unsigned int outlen;
76-
int ret = -ENOMEM;
76+
int ret;
7777

7878
pr_devel("==>%s()\n", __func__);
7979

@@ -99,6 +99,7 @@ int public_key_verify_signature(const struct public_key *pkey,
9999
if (IS_ERR(tfm))
100100
return PTR_ERR(tfm);
101101

102+
ret = -ENOMEM;
102103
req = akcipher_request_alloc(tfm, GFP_KERNEL);
103104
if (!req)
104105
goto error_free_tfm;
@@ -127,7 +128,7 @@ int public_key_verify_signature(const struct public_key *pkey,
127128
* signature and returns that to us.
128129
*/
129130
ret = crypto_wait_req(crypto_akcipher_verify(req), &cwait);
130-
if (ret < 0)
131+
if (ret)
131132
goto out_free_output;
132133

133134
/* Do the actual verification step. */
@@ -142,6 +143,8 @@ int public_key_verify_signature(const struct public_key *pkey,
142143
error_free_tfm:
143144
crypto_free_akcipher(tfm);
144145
pr_devel("<==%s() = %d\n", __func__, ret);
146+
if (WARN_ON_ONCE(ret > 0))
147+
ret = -EINVAL;
145148
return ret;
146149
}
147150
EXPORT_SYMBOL_GPL(public_key_verify_signature);

crypto/asymmetric_keys/x509_cert_parser.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -409,6 +409,8 @@ int x509_extract_key_data(void *context, size_t hdrlen,
409409
ctx->cert->pub->pkey_algo = "rsa";
410410

411411
/* Discard the BIT STRING metadata */
412+
if (vlen < 1 || *(const u8 *)value != 0)
413+
return -EBADMSG;
412414
ctx->key = value + 1;
413415
ctx->key_size = vlen - 1;
414416
return 0;

crypto/asymmetric_keys/x509_public_key.c

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -79,11 +79,7 @@ int x509_get_sig_params(struct x509_certificate *cert)
7979
desc->tfm = tfm;
8080
desc->flags = CRYPTO_TFM_REQ_MAY_SLEEP;
8181

82-
ret = crypto_shash_init(desc);
83-
if (ret < 0)
84-
goto error_2;
85-
might_sleep();
86-
ret = crypto_shash_finup(desc, cert->tbs, cert->tbs_size, sig->digest);
82+
ret = crypto_shash_digest(desc, cert->tbs, cert->tbs_size, sig->digest);
8783
if (ret < 0)
8884
goto error_2;
8985

@@ -135,7 +131,7 @@ int x509_check_for_self_signed(struct x509_certificate *cert)
135131
}
136132

137133
ret = -EKEYREJECTED;
138-
if (cert->pub->pkey_algo != cert->sig->pkey_algo)
134+
if (strcmp(cert->pub->pkey_algo, cert->sig->pkey_algo) != 0)
139135
goto out;
140136

141137
ret = public_key_verify_signature(cert->pub, cert->sig);

lib/asn1_decoder.c

Lines changed: 28 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -313,42 +313,47 @@ int asn1_ber_decoder(const struct asn1_decoder *decoder,
313313

314314
/* Decide how to handle the operation */
315315
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-
333316
case ASN1_OP_MATCH:
334317
case ASN1_OP_MATCH_OR_SKIP:
318+
case ASN1_OP_MATCH_ACT:
319+
case ASN1_OP_MATCH_ACT_OR_SKIP:
335320
case ASN1_OP_MATCH_ANY:
336321
case ASN1_OP_MATCH_ANY_OR_SKIP:
322+
case ASN1_OP_MATCH_ANY_ACT:
323+
case ASN1_OP_MATCH_ANY_ACT_OR_SKIP:
337324
case ASN1_OP_COND_MATCH_OR_SKIP:
325+
case ASN1_OP_COND_MATCH_ACT_OR_SKIP:
338326
case ASN1_OP_COND_MATCH_ANY:
339327
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+
341331
if (!(flags & FLAG_CONS)) {
342332
if (flags & FLAG_INDEFINITE_LENGTH) {
333+
size_t tmp = dp;
334+
343335
ret = asn1_find_indefinite_length(
344-
data, datalen, &dp, &len, &errmsg);
336+
data, datalen, &tmp, &len, &errmsg);
345337
if (ret < 0)
346338
goto error;
347-
} else {
348-
dp += len;
349339
}
350340
pr_debug("- LEAF: %zu\n", len);
351341
}
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;
352357
pc += asn1_op_lengths[op];
353358
goto next_op;
354359

@@ -434,6 +439,8 @@ int asn1_ber_decoder(const struct asn1_decoder *decoder,
434439
else
435440
act = machine[pc + 1];
436441
ret = actions[act](context, hdr, 0, data + tdp, len);
442+
if (ret < 0)
443+
return ret;
437444
}
438445
pc += asn1_op_lengths[op];
439446
goto next_op;

lib/oid_registry.c

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -116,14 +116,14 @@ int sprint_oid(const void *data, size_t datasize, char *buffer, size_t bufsize)
116116
int count;
117117

118118
if (v >= end)
119-
return -EBADMSG;
119+
goto bad;
120120

121121
n = *v++;
122122
ret = count = snprintf(buffer, bufsize, "%u.%u", n / 40, n % 40);
123+
if (count >= bufsize)
124+
return -ENOBUFS;
123125
buffer += count;
124126
bufsize -= count;
125-
if (bufsize == 0)
126-
return -ENOBUFS;
127127

128128
while (v < end) {
129129
num = 0;
@@ -134,20 +134,24 @@ int sprint_oid(const void *data, size_t datasize, char *buffer, size_t bufsize)
134134
num = n & 0x7f;
135135
do {
136136
if (v >= end)
137-
return -EBADMSG;
137+
goto bad;
138138
n = *v++;
139139
num <<= 7;
140140
num |= n & 0x7f;
141141
} while (n & 0x80);
142142
}
143143
ret += count = snprintf(buffer, bufsize, ".%lu", num);
144-
buffer += count;
145-
if (bufsize <= count)
144+
if (count >= bufsize)
146145
return -ENOBUFS;
146+
buffer += count;
147147
bufsize -= count;
148148
}
149149

150150
return ret;
151+
152+
bad:
153+
snprintf(buffer, bufsize, "(bad)");
154+
return -EBADMSG;
151155
}
152156
EXPORT_SYMBOL_GPL(sprint_oid);
153157

security/keys/key.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -833,7 +833,6 @@ key_ref_t key_create_or_update(key_ref_t keyring_ref,
833833

834834
key_check(keyring);
835835

836-
key_ref = ERR_PTR(-EPERM);
837836
if (!(flags & KEY_ALLOC_BYPASS_RESTRICTION))
838837
restrict_link = keyring->restrict_link;
839838

security/keys/keyctl.c

Lines changed: 10 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1588,17 +1588,15 @@ long keyctl_session_to_parent(void)
15881588
* The caller must have Setattr permission to change keyring restrictions.
15891589
*
15901590
* 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 be
1592-
* NULL or a pointer to a string describing the restriction. If _type is
1593-
* NULL, _restriction must also be NULL.
1591+
* to link to the keyring. In this case, _restriction must also be NULL.
1592+
* Otherwise, both _type and _restriction must be non-NULL.
15941593
*
15951594
* Returns 0 if successful.
15961595
*/
15971596
long keyctl_restrict_keyring(key_serial_t id, const char __user *_type,
15981597
const char __user *_restriction)
15991598
{
16001599
key_ref_t key_ref;
1601-
bool link_reject = !_type;
16021600
char type[32];
16031601
char *restriction = NULL;
16041602
long ret;
@@ -1607,31 +1605,29 @@ long keyctl_restrict_keyring(key_serial_t id, const char __user *_type,
16071605
if (IS_ERR(key_ref))
16081606
return PTR_ERR(key_ref);
16091607

1608+
ret = -EINVAL;
16101609
if (_type) {
1611-
ret = key_get_type_from_user(type, _type, sizeof(type));
1612-
if (ret < 0)
1610+
if (!_restriction)
16131611
goto error;
1614-
}
16151612

1616-
if (_restriction) {
1617-
if (!_type) {
1618-
ret = -EINVAL;
1613+
ret = key_get_type_from_user(type, _type, sizeof(type));
1614+
if (ret < 0)
16191615
goto error;
1620-
}
16211616

16221617
restriction = strndup_user(_restriction, PAGE_SIZE);
16231618
if (IS_ERR(restriction)) {
16241619
ret = PTR_ERR(restriction);
16251620
goto error;
16261621
}
1622+
} else {
1623+
if (_restriction)
1624+
goto error;
16271625
}
16281626

1629-
ret = keyring_restrict(key_ref, link_reject ? NULL : type, restriction);
1627+
ret = keyring_restrict(key_ref, _type ? type : NULL, restriction);
16301628
kfree(restriction);
1631-
16321629
error:
16331630
key_ref_put(key_ref);
1634-
16351631
return ret;
16361632
}
16371633

0 commit comments

Comments
 (0)