mirror of https://gitee.com/openkylin/linux.git
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/linux-security
Pull security subsystem fixes from James Morris:
"This includes several fixes for TPM, as well as a fix for the x.509
certificate parser to address CVE-2015-5327"
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/linux-security:
X.509: Fix the time validation [ver #2]
tpm: fix compat 'ppi' link handling in tpm_chip_register()
tpm: fix missing migratable flag in sealing functionality for TPM2
TPM: revert the list handling logic fixed in 398a1e7
TPM: Avoid reference to potentially freed memory
tpm_tis: restore IRQ vector in IO memory after failed probing
tpm_tis: free irq after probing
This commit is contained in:
commit
a4d8c7c9f7
|
@ -531,7 +531,11 @@ int x509_decode_time(time64_t *_t, size_t hdrlen,
|
||||||
if (*p != 'Z')
|
if (*p != 'Z')
|
||||||
goto unsupported_time;
|
goto unsupported_time;
|
||||||
|
|
||||||
mon_len = month_lengths[mon];
|
if (year < 1970 ||
|
||||||
|
mon < 1 || mon > 12)
|
||||||
|
goto invalid_time;
|
||||||
|
|
||||||
|
mon_len = month_lengths[mon - 1];
|
||||||
if (mon == 2) {
|
if (mon == 2) {
|
||||||
if (year % 4 == 0) {
|
if (year % 4 == 0) {
|
||||||
mon_len = 29;
|
mon_len = 29;
|
||||||
|
@ -543,14 +547,12 @@ int x509_decode_time(time64_t *_t, size_t hdrlen,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (year < 1970 ||
|
if (day < 1 || day > mon_len ||
|
||||||
mon < 1 || mon > 12 ||
|
|
||||||
day < 1 || day > mon_len ||
|
|
||||||
hour > 23 ||
|
hour > 23 ||
|
||||||
min > 59 ||
|
min > 59 ||
|
||||||
sec > 59)
|
sec > 59)
|
||||||
goto invalid_time;
|
goto invalid_time;
|
||||||
|
|
||||||
*_t = mktime64(year, mon, day, hour, min, sec);
|
*_t = mktime64(year, mon, day, hour, min, sec);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
|
|
@ -226,21 +226,23 @@ int tpm_chip_register(struct tpm_chip *chip)
|
||||||
if (rc)
|
if (rc)
|
||||||
goto out_err;
|
goto out_err;
|
||||||
|
|
||||||
|
/* Make the chip available. */
|
||||||
|
spin_lock(&driver_lock);
|
||||||
|
list_add_tail_rcu(&chip->list, &tpm_chip_list);
|
||||||
|
spin_unlock(&driver_lock);
|
||||||
|
|
||||||
|
chip->flags |= TPM_CHIP_FLAG_REGISTERED;
|
||||||
|
|
||||||
if (!(chip->flags & TPM_CHIP_FLAG_TPM2)) {
|
if (!(chip->flags & TPM_CHIP_FLAG_TPM2)) {
|
||||||
rc = __compat_only_sysfs_link_entry_to_kobj(&chip->pdev->kobj,
|
rc = __compat_only_sysfs_link_entry_to_kobj(&chip->pdev->kobj,
|
||||||
&chip->dev.kobj,
|
&chip->dev.kobj,
|
||||||
"ppi");
|
"ppi");
|
||||||
if (rc)
|
if (rc && rc != -ENOENT) {
|
||||||
goto out_err;
|
tpm_chip_unregister(chip);
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Make the chip available. */
|
|
||||||
spin_lock(&driver_lock);
|
|
||||||
list_add_rcu(&chip->list, &tpm_chip_list);
|
|
||||||
spin_unlock(&driver_lock);
|
|
||||||
|
|
||||||
chip->flags |= TPM_CHIP_FLAG_REGISTERED;
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
out_err:
|
out_err:
|
||||||
tpm1_chip_unregister(chip);
|
tpm1_chip_unregister(chip);
|
||||||
|
|
|
@ -443,12 +443,13 @@ int tpm2_seal_trusted(struct tpm_chip *chip,
|
||||||
TPM_DIGEST_SIZE);
|
TPM_DIGEST_SIZE);
|
||||||
|
|
||||||
/* sensitive */
|
/* sensitive */
|
||||||
tpm_buf_append_u16(&buf, 4 + TPM_DIGEST_SIZE + payload->key_len);
|
tpm_buf_append_u16(&buf, 4 + TPM_DIGEST_SIZE + payload->key_len + 1);
|
||||||
|
|
||||||
tpm_buf_append_u16(&buf, TPM_DIGEST_SIZE);
|
tpm_buf_append_u16(&buf, TPM_DIGEST_SIZE);
|
||||||
tpm_buf_append(&buf, options->blobauth, TPM_DIGEST_SIZE);
|
tpm_buf_append(&buf, options->blobauth, TPM_DIGEST_SIZE);
|
||||||
tpm_buf_append_u16(&buf, payload->key_len);
|
tpm_buf_append_u16(&buf, payload->key_len + 1);
|
||||||
tpm_buf_append(&buf, payload->key, payload->key_len);
|
tpm_buf_append(&buf, payload->key, payload->key_len);
|
||||||
|
tpm_buf_append_u8(&buf, payload->migratable);
|
||||||
|
|
||||||
/* public */
|
/* public */
|
||||||
tpm_buf_append_u16(&buf, 14);
|
tpm_buf_append_u16(&buf, 14);
|
||||||
|
@ -573,6 +574,8 @@ static int tpm2_unseal(struct tpm_chip *chip,
|
||||||
u32 blob_handle)
|
u32 blob_handle)
|
||||||
{
|
{
|
||||||
struct tpm_buf buf;
|
struct tpm_buf buf;
|
||||||
|
u16 data_len;
|
||||||
|
u8 *data;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
rc = tpm_buf_init(&buf, TPM2_ST_SESSIONS, TPM2_CC_UNSEAL);
|
rc = tpm_buf_init(&buf, TPM2_ST_SESSIONS, TPM2_CC_UNSEAL);
|
||||||
|
@ -591,11 +594,13 @@ static int tpm2_unseal(struct tpm_chip *chip,
|
||||||
rc = -EPERM;
|
rc = -EPERM;
|
||||||
|
|
||||||
if (!rc) {
|
if (!rc) {
|
||||||
payload->key_len = be16_to_cpup(
|
data_len = be16_to_cpup(
|
||||||
(__be16 *) &buf.data[TPM_HEADER_SIZE + 4]);
|
(__be16 *) &buf.data[TPM_HEADER_SIZE + 4]);
|
||||||
|
data = &buf.data[TPM_HEADER_SIZE + 6];
|
||||||
|
|
||||||
memcpy(payload->key, &buf.data[TPM_HEADER_SIZE + 6],
|
memcpy(payload->key, data, data_len - 1);
|
||||||
payload->key_len);
|
payload->key_len = data_len - 1;
|
||||||
|
payload->migratable = data[data_len - 1];
|
||||||
}
|
}
|
||||||
|
|
||||||
tpm_buf_destroy(&buf);
|
tpm_buf_destroy(&buf);
|
||||||
|
|
|
@ -53,17 +53,18 @@ int read_log(struct tpm_bios_log *log)
|
||||||
goto cleanup_eio;
|
goto cleanup_eio;
|
||||||
}
|
}
|
||||||
|
|
||||||
of_node_put(np);
|
|
||||||
log->bios_event_log = kmalloc(*sizep, GFP_KERNEL);
|
log->bios_event_log = kmalloc(*sizep, GFP_KERNEL);
|
||||||
if (!log->bios_event_log) {
|
if (!log->bios_event_log) {
|
||||||
pr_err("%s: ERROR - Not enough memory for BIOS measurements\n",
|
pr_err("%s: ERROR - Not enough memory for BIOS measurements\n",
|
||||||
__func__);
|
__func__);
|
||||||
|
of_node_put(np);
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
log->bios_event_log_end = log->bios_event_log + *sizep;
|
log->bios_event_log_end = log->bios_event_log + *sizep;
|
||||||
|
|
||||||
memcpy(log->bios_event_log, __va(*basep), *sizep);
|
memcpy(log->bios_event_log, __va(*basep), *sizep);
|
||||||
|
of_node_put(np);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
|
|
@ -645,6 +645,7 @@ static int tpm_tis_init(struct device *dev, struct tpm_info *tpm_info,
|
||||||
{
|
{
|
||||||
u32 vendor, intfcaps, intmask;
|
u32 vendor, intfcaps, intmask;
|
||||||
int rc, i, irq_s, irq_e, probe;
|
int rc, i, irq_s, irq_e, probe;
|
||||||
|
int irq_r = -1;
|
||||||
struct tpm_chip *chip;
|
struct tpm_chip *chip;
|
||||||
struct priv_data *priv;
|
struct priv_data *priv;
|
||||||
|
|
||||||
|
@ -751,6 +752,7 @@ static int tpm_tis_init(struct device *dev, struct tpm_info *tpm_info,
|
||||||
irq_s =
|
irq_s =
|
||||||
ioread8(chip->vendor.iobase +
|
ioread8(chip->vendor.iobase +
|
||||||
TPM_INT_VECTOR(chip->vendor.locality));
|
TPM_INT_VECTOR(chip->vendor.locality));
|
||||||
|
irq_r = irq_s;
|
||||||
if (irq_s) {
|
if (irq_s) {
|
||||||
irq_e = irq_s;
|
irq_e = irq_s;
|
||||||
} else {
|
} else {
|
||||||
|
@ -805,6 +807,8 @@ static int tpm_tis_init(struct device *dev, struct tpm_info *tpm_info,
|
||||||
iowrite32(intmask,
|
iowrite32(intmask,
|
||||||
chip->vendor.iobase +
|
chip->vendor.iobase +
|
||||||
TPM_INT_ENABLE(chip->vendor.locality));
|
TPM_INT_ENABLE(chip->vendor.locality));
|
||||||
|
|
||||||
|
devm_free_irq(dev, i, chip);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (chip->vendor.irq) {
|
if (chip->vendor.irq) {
|
||||||
|
@ -831,7 +835,9 @@ static int tpm_tis_init(struct device *dev, struct tpm_info *tpm_info,
|
||||||
chip->vendor.iobase +
|
chip->vendor.iobase +
|
||||||
TPM_INT_ENABLE(chip->vendor.locality));
|
TPM_INT_ENABLE(chip->vendor.locality));
|
||||||
}
|
}
|
||||||
}
|
} else if (irq_r != -1)
|
||||||
|
iowrite8(irq_r, chip->vendor.iobase +
|
||||||
|
TPM_INT_VECTOR(chip->vendor.locality));
|
||||||
|
|
||||||
if (chip->flags & TPM_CHIP_FLAG_TPM2) {
|
if (chip->flags & TPM_CHIP_FLAG_TPM2) {
|
||||||
chip->vendor.timeout_a = msecs_to_jiffies(TPM2_TIMEOUT_A);
|
chip->vendor.timeout_a = msecs_to_jiffies(TPM2_TIMEOUT_A);
|
||||||
|
|
Loading…
Reference in New Issue