From 7f368ad34f0657f4bc39bf5bad6692b5a81a1194 Mon Sep 17 00:00:00 2001 From: Casey Schaufler Date: Wed, 11 Feb 2015 12:52:32 -0800 Subject: Smack: secmark connections If the secmark is available us it on connection as well as packet delivery. Signed-off-by: Casey Schaufler diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c index a0ccce4..ed94f6f 100644 --- a/security/smack/smack_lsm.c +++ b/security/smack/smack_lsm.c @@ -3818,6 +3818,18 @@ static int smack_inet_conn_request(struct sock *sk, struct sk_buff *skb, } #endif /* CONFIG_IPV6 */ +#ifdef CONFIG_SECURITY_SMACK_NETFILTER + /* + * If there is a secmark use it rather than the CIPSO label. + * If there is no secmark fall back to CIPSO. + * The secmark is assumed to reflect policy better. + */ + if (skb && skb->secmark != 0) { + skp = smack_from_secid(skb->secmark); + goto access_check; + } +#endif /* CONFIG_SECURITY_SMACK_NETFILTER */ + netlbl_secattr_init(&secattr); rc = netlbl_skbuff_getattr(skb, family, &secattr); if (rc == 0) @@ -3826,6 +3838,10 @@ static int smack_inet_conn_request(struct sock *sk, struct sk_buff *skb, skp = &smack_known_huh; netlbl_secattr_destroy(&secattr); +#ifdef CONFIG_SECURITY_SMACK_NETFILTER +access_check: +#endif + #ifdef CONFIG_AUDIT smk_ad_init_net(&ad, __func__, LSM_AUDIT_DATA_NET, &net); ad.a.u.net->family = family; -- cgit v0.10.2 From 74d6b3ceaa17d111220c3f09f50f901bf955d7c8 Mon Sep 17 00:00:00 2001 From: Jarkko Sakkinen Date: Thu, 29 Jan 2015 07:43:47 +0200 Subject: tpm: fix suspend/resume paths for TPM 2.0 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixed suspend/resume paths for TPM 2.0 and consolidated all the associated code to the tpm_pm_suspend() and tpm_pm_resume() functions. Resume path should be handled by the firmware, i.e. Startup(CLEAR) for hibernate and Startup(STATE) for suspend. There might be some non-PC embedded devices in the future where Startup() is not the handled by the FW but fixing the code for those IMHO should be postponed until there is hardware available to test the fixes although extra Startup in the driver code is essentially a NOP. Added Shutdown(CLEAR) to the remove paths of TIS and CRB drivers. Changed tpm2_shutdown() to a void function because there isn't much you can do except print an error message if this fails with a system error. Fixes: aec04cbdf723 ("tpm: TPM 2.0 FIFO Interface") Fixes: 30fc8d138e91 ("tpm: TPM 2.0 CRB Interface") [phuewe: both did send TPM_Shutdown on resume which 'disables' the TPM and did not send TPM2_Shutdown on teardown which leads some TPM2.0 to believe there was an attack (no TPM2_Shutdown = no orderly shutdown = attack)] Reported-by: Peter Hüwe Signed-off-by: Jarkko Sakkinen Tested-by: Scot Doyle Reviewed-by: Peter Huewe Signed-off-by: Peter Huewe diff --git a/drivers/char/tpm/tpm-interface.c b/drivers/char/tpm/tpm-interface.c index bf53a37..e85d341 100644 --- a/drivers/char/tpm/tpm-interface.c +++ b/drivers/char/tpm/tpm-interface.c @@ -901,8 +901,10 @@ int tpm_pm_suspend(struct device *dev) if (chip == NULL) return -ENODEV; - if (chip->flags & TPM_CHIP_FLAG_TPM2) - return tpm2_shutdown(chip, TPM2_SU_CLEAR); + if (chip->flags & TPM_CHIP_FLAG_TPM2) { + tpm2_shutdown(chip, TPM2_SU_STATE); + return 0; + } /* for buggy tpm, flush pcrs with extend to selected dummy */ if (tpm_suspend_pcr) { diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h index 7b0727c..a2ce379 100644 --- a/drivers/char/tpm/tpm.h +++ b/drivers/char/tpm/tpm.h @@ -432,7 +432,7 @@ ssize_t tpm2_get_tpm_pt(struct tpm_chip *chip, u32 property_id, u32 *value, const char *desc); extern int tpm2_startup(struct tpm_chip *chip, u16 startup_type); -extern int tpm2_shutdown(struct tpm_chip *chip, u16 shutdown_type); +extern void tpm2_shutdown(struct tpm_chip *chip, u16 shutdown_type); extern unsigned long tpm2_calc_ordinal_duration(struct tpm_chip *, u32); extern int tpm2_do_selftest(struct tpm_chip *chip); extern int tpm2_gen_interrupt(struct tpm_chip *chip, bool quiet); diff --git a/drivers/char/tpm/tpm2-cmd.c b/drivers/char/tpm/tpm2-cmd.c index 1abe650..f2f38a5 100644 --- a/drivers/char/tpm/tpm2-cmd.c +++ b/drivers/char/tpm/tpm2-cmd.c @@ -456,20 +456,23 @@ static const struct tpm_input_header tpm2_shutdown_header = { * @chip: TPM chip to use. * @shutdown_type shutdown type. The value is either * TPM_SU_CLEAR or TPM_SU_STATE. - * - * 0 is returned when the operation is successful. If a negative number is - * returned it remarks a POSIX error code. If a positive number is returned - * it remarks a TPM error. */ -int tpm2_shutdown(struct tpm_chip *chip, u16 shutdown_type) +void tpm2_shutdown(struct tpm_chip *chip, u16 shutdown_type) { struct tpm2_cmd cmd; + int rc; cmd.header.in = tpm2_shutdown_header; - cmd.params.startup_in.startup_type = cpu_to_be16(shutdown_type); - return tpm_transmit_cmd(chip, &cmd, sizeof(cmd), - "stopping the TPM"); + + rc = tpm_transmit_cmd(chip, &cmd, sizeof(cmd), "stopping the TPM"); + + /* In places where shutdown command is sent there's no much we can do + * except print the error code on a system failure. + */ + if (rc < 0) + dev_warn(chip->pdev, "transmit returned %d while stopping the TPM", + rc); } EXPORT_SYMBOL_GPL(tpm2_shutdown); diff --git a/drivers/char/tpm/tpm_crb.c b/drivers/char/tpm/tpm_crb.c index 3dd23cf..b26ceee 100644 --- a/drivers/char/tpm/tpm_crb.c +++ b/drivers/char/tpm/tpm_crb.c @@ -95,21 +95,7 @@ struct crb_priv { u8 __iomem *rsp; }; -#ifdef CONFIG_PM_SLEEP -static int crb_resume(struct device *dev) -{ - int rc; - struct tpm_chip *chip = dev_get_drvdata(dev); - - rc = tpm2_shutdown(chip, TPM2_SU_STATE); - if (!rc) - rc = tpm2_do_selftest(chip); - - return rc; -} -#endif - -static SIMPLE_DEV_PM_OPS(crb_pm, tpm_pm_suspend, crb_resume); +static SIMPLE_DEV_PM_OPS(crb_pm, tpm_pm_suspend, tpm_pm_resume); static u8 crb_status(struct tpm_chip *chip) { @@ -326,6 +312,10 @@ static int crb_acpi_remove(struct acpi_device *device) struct tpm_chip *chip = dev_get_drvdata(dev); tpm_chip_unregister(chip); + + if (chip->flags & TPM_CHIP_FLAG_TPM2) + tpm2_shutdown(chip, TPM2_SU_CLEAR); + return 0; } diff --git a/drivers/char/tpm/tpm_tis.c b/drivers/char/tpm/tpm_tis.c index 6725bef..e12b3ab 100644 --- a/drivers/char/tpm/tpm_tis.c +++ b/drivers/char/tpm/tpm_tis.c @@ -588,6 +588,9 @@ MODULE_PARM_DESC(interrupts, "Enable interrupts"); static void tpm_tis_remove(struct tpm_chip *chip) { + if (chip->flags & TPM_CHIP_FLAG_TPM2) + tpm2_shutdown(chip, TPM2_SU_CLEAR); + iowrite32(~TPM_GLOBAL_INT_ENABLE & ioread32(chip->vendor.iobase + TPM_INT_ENABLE(chip->vendor. @@ -865,25 +868,22 @@ static void tpm_tis_reenable_interrupts(struct tpm_chip *chip) static int tpm_tis_resume(struct device *dev) { struct tpm_chip *chip = dev_get_drvdata(dev); - int ret = 0; + int ret; if (chip->vendor.irq) tpm_tis_reenable_interrupts(chip); - if (chip->flags & TPM_CHIP_FLAG_TPM2) { - /* NOP if firmware properly does this. */ - tpm2_startup(chip, TPM2_SU_STATE); + ret = tpm_pm_resume(dev); + if (ret) + return ret; - ret = tpm2_shutdown(chip, TPM2_SU_STATE); - if (!ret) - ret = tpm2_do_selftest(chip); - } else { - ret = tpm_pm_resume(dev); - if (!ret) - tpm_do_selftest(chip); - } + /* TPM 1.2 requires self-test on resume. This function actually returns + * an error code but for unknown reason it isn't handled. + */ + if (!(chip->flags & TPM_CHIP_FLAG_TPM2)) + tpm_do_selftest(chip); - return ret; + return 0; } #endif -- cgit v0.10.2 From 4d5f2051cd24adc19a645e920344e05afe8d69b9 Mon Sep 17 00:00:00 2001 From: Jarkko Sakkinen Date: Wed, 4 Feb 2015 16:21:09 +0200 Subject: tpm, tpm_tis: fix TPM 2.0 probing If during transmission system error was returned, the logic was to incorrectly deduce that chip is a TPM 1.x chip. This patch fixes this issue. Also, this patch changes probing so that message tag is used as the measure for TPM 2.x, which should be much more stable. A separate function called tpm2_probe() is encapsulated because it can be used with any chipset. Fixes: aec04cbdf723 ("tpm: TPM 2.0 FIFO Interface") Signed-off-by: Jarkko Sakkinen Reviewed-by: Stefan Berger Reviewed-by: Peter Huewe Signed-off-by: Peter Huewe diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h index a2ce379..f8319a0 100644 --- a/drivers/char/tpm/tpm.h +++ b/drivers/char/tpm/tpm.h @@ -435,4 +435,5 @@ extern int tpm2_startup(struct tpm_chip *chip, u16 startup_type); extern void tpm2_shutdown(struct tpm_chip *chip, u16 shutdown_type); extern unsigned long tpm2_calc_ordinal_duration(struct tpm_chip *, u32); extern int tpm2_do_selftest(struct tpm_chip *chip); -extern int tpm2_gen_interrupt(struct tpm_chip *chip, bool quiet); +extern int tpm2_gen_interrupt(struct tpm_chip *chip); +extern int tpm2_probe(struct tpm_chip *chip); diff --git a/drivers/char/tpm/tpm2-cmd.c b/drivers/char/tpm/tpm2-cmd.c index f2f38a5..011909a 100644 --- a/drivers/char/tpm/tpm2-cmd.c +++ b/drivers/char/tpm/tpm2-cmd.c @@ -601,20 +601,46 @@ EXPORT_SYMBOL_GPL(tpm2_do_selftest); /** * tpm2_gen_interrupt() - generate an interrupt * @chip: TPM chip to use - * @quiet: surpress the error message * * 0 is returned when the operation is successful. If a negative number is * returned it remarks a POSIX error code. If a positive number is returned * it remarks a TPM error. */ -int tpm2_gen_interrupt(struct tpm_chip *chip, bool quiet) +int tpm2_gen_interrupt(struct tpm_chip *chip) { - const char *desc = NULL; u32 dummy; - if (!quiet) - desc = "attempting to generate an interrupt"; - - return tpm2_get_tpm_pt(chip, TPM2_CAP_TPM_PROPERTIES, &dummy, desc); + return tpm2_get_tpm_pt(chip, 0x100, &dummy, + "attempting to generate an interrupt"); } EXPORT_SYMBOL_GPL(tpm2_gen_interrupt); + +/** + * tpm2_probe() - probe TPM 2.0 + * @chip: TPM chip to use + * + * Send idempotent TPM 2.0 command and see whether TPM 2.0 chip replied based on + * the reply tag. + */ +int tpm2_probe(struct tpm_chip *chip) +{ + struct tpm2_cmd cmd; + int rc; + + cmd.header.in = tpm2_get_tpm_pt_header; + cmd.params.get_tpm_pt_in.cap_id = cpu_to_be32(TPM2_CAP_TPM_PROPERTIES); + cmd.params.get_tpm_pt_in.property_id = cpu_to_be32(0x100); + cmd.params.get_tpm_pt_in.property_cnt = cpu_to_be32(1); + + rc = tpm_transmit(chip, (const char *) &cmd, sizeof(cmd)); + if (rc < 0) + return rc; + else if (rc < TPM_HEADER_SIZE) + return -EFAULT; + + if (be16_to_cpu(cmd.header.out.tag) == TPM2_ST_NO_SESSIONS) + chip->flags |= TPM_CHIP_FLAG_TPM2; + + return 0; +} +EXPORT_SYMBOL_GPL(tpm2_probe); diff --git a/drivers/char/tpm/tpm_tis.c b/drivers/char/tpm/tpm_tis.c index e12b3ab..f2dffa7 100644 --- a/drivers/char/tpm/tpm_tis.c +++ b/drivers/char/tpm/tpm_tis.c @@ -642,12 +642,9 @@ static int tpm_tis_init(struct device *dev, acpi_handle acpi_dev_handle, goto out_err; } - /* Every TPM 2.x command has a higher ordinal than TPM 1.x commands. - * Therefore, we can use an idempotent TPM 2.x command to probe TPM 2.x. - */ - rc = tpm2_gen_interrupt(chip, true); - if (rc == 0 || rc == TPM2_RC_INITIALIZE) - chip->flags |= TPM_CHIP_FLAG_TPM2; + rc = tpm2_probe(chip); + if (rc) + goto out_err; vendor = ioread32(chip->vendor.iobase + TPM_DID_VID(0)); chip->vendor.manufacturer_id = vendor; @@ -750,7 +747,7 @@ static int tpm_tis_init(struct device *dev, acpi_handle acpi_dev_handle, /* Generate Interrupts */ if (chip->flags & TPM_CHIP_FLAG_TPM2) - tpm2_gen_interrupt(chip, false); + tpm2_gen_interrupt(chip); else tpm_gen_interrupt(chip); -- cgit v0.10.2 From eb71f8a5e33fa1066fb92f0111ab366a341e1f6c Mon Sep 17 00:00:00 2001 From: honclo Date: Thu, 12 Feb 2015 21:02:24 -0500 Subject: Added Little Endian support to vtpm module The tpm_ibmvtpm module is affected by an unaligned access problem. ibmvtpm_crq_get_version failed with rc=-4 during boot when vTPM is enabled in Power partition, which supports both little endian and big endian modes. We added little endian support to fix this problem: 1) added cpu_to_be64 calls to ensure BE data is sent from an LE OS. 2) added be16_to_cpu and be32_to_cpu calls to make sure data received is in LE format on a LE OS. Signed-off-by: Hon Ching(Vicky) Lo Signed-off-by: Joy Latten Cc: [phuewe: manually applied the patch :( ] Reviewed-by: Ashley Lai Signed-off-by: Peter Huewe diff --git a/drivers/char/tpm/tpm_ibmvtpm.c b/drivers/char/tpm/tpm_ibmvtpm.c index 0840347..b1e53e3 100644 --- a/drivers/char/tpm/tpm_ibmvtpm.c +++ b/drivers/char/tpm/tpm_ibmvtpm.c @@ -148,7 +148,8 @@ static int tpm_ibmvtpm_send(struct tpm_chip *chip, u8 *buf, size_t count) crq.len = (u16)count; crq.data = ibmvtpm->rtce_dma_handle; - rc = ibmvtpm_send_crq(ibmvtpm->vdev, word[0], word[1]); + rc = ibmvtpm_send_crq(ibmvtpm->vdev, cpu_to_be64(word[0]), + cpu_to_be64(word[1])); if (rc != H_SUCCESS) { dev_err(ibmvtpm->dev, "tpm_ibmvtpm_send failed rc=%d\n", rc); rc = 0; @@ -186,7 +187,8 @@ static int ibmvtpm_crq_get_rtce_size(struct ibmvtpm_dev *ibmvtpm) crq.valid = (u8)IBMVTPM_VALID_CMD; crq.msg = (u8)VTPM_GET_RTCE_BUFFER_SIZE; - rc = ibmvtpm_send_crq(ibmvtpm->vdev, buf[0], buf[1]); + rc = ibmvtpm_send_crq(ibmvtpm->vdev, cpu_to_be64(buf[0]), + cpu_to_be64(buf[1])); if (rc != H_SUCCESS) dev_err(ibmvtpm->dev, "ibmvtpm_crq_get_rtce_size failed rc=%d\n", rc); @@ -212,7 +214,8 @@ static int ibmvtpm_crq_get_version(struct ibmvtpm_dev *ibmvtpm) crq.valid = (u8)IBMVTPM_VALID_CMD; crq.msg = (u8)VTPM_GET_VERSION; - rc = ibmvtpm_send_crq(ibmvtpm->vdev, buf[0], buf[1]); + rc = ibmvtpm_send_crq(ibmvtpm->vdev, cpu_to_be64(buf[0]), + cpu_to_be64(buf[1])); if (rc != H_SUCCESS) dev_err(ibmvtpm->dev, "ibmvtpm_crq_get_version failed rc=%d\n", rc); @@ -336,7 +339,8 @@ static int tpm_ibmvtpm_suspend(struct device *dev) crq.valid = (u8)IBMVTPM_VALID_CMD; crq.msg = (u8)VTPM_PREPARE_TO_SUSPEND; - rc = ibmvtpm_send_crq(ibmvtpm->vdev, buf[0], buf[1]); + rc = ibmvtpm_send_crq(ibmvtpm->vdev, cpu_to_be64(buf[0]), + cpu_to_be64(buf[1])); if (rc != H_SUCCESS) dev_err(ibmvtpm->dev, "tpm_ibmvtpm_suspend failed rc=%d\n", rc); @@ -481,11 +485,11 @@ static void ibmvtpm_crq_process(struct ibmvtpm_crq *crq, case IBMVTPM_VALID_CMD: switch (crq->msg) { case VTPM_GET_RTCE_BUFFER_SIZE_RES: - if (crq->len <= 0) { + if (be16_to_cpu(crq->len) <= 0) { dev_err(ibmvtpm->dev, "Invalid rtce size\n"); return; } - ibmvtpm->rtce_size = crq->len; + ibmvtpm->rtce_size = be16_to_cpu(crq->len); ibmvtpm->rtce_buf = kmalloc(ibmvtpm->rtce_size, GFP_KERNEL); if (!ibmvtpm->rtce_buf) { @@ -506,11 +510,11 @@ static void ibmvtpm_crq_process(struct ibmvtpm_crq *crq, return; case VTPM_GET_VERSION_RES: - ibmvtpm->vtpm_version = crq->data; + ibmvtpm->vtpm_version = be32_to_cpu(crq->data); return; case VTPM_TPM_COMMAND_RES: /* len of the data in rtce buffer */ - ibmvtpm->res_len = crq->len; + ibmvtpm->res_len = be16_to_cpu(crq->len); wake_up_interruptible(&ibmvtpm->wq); return; default: -- cgit v0.10.2 From d0709f1e66e8066c4ac6a54620ec116aa41937c0 Mon Sep 17 00:00:00 2001 From: David Jeffery Date: Thu, 12 Feb 2015 16:45:31 +0000 Subject: Don't leak a key reference if request_key() tries to use a revoked keyring If a request_key() call to allocate and fill out a key attempts to insert the key structure into a revoked keyring, the key will leak, using memory and part of the user's key quota until the system reboots. This is from a failure of construct_alloc_key() to decrement the key's reference count after the attempt to insert into the requested keyring is rejected. key_put() needs to be called in the link_prealloc_failed callpath to ensure the unused key is released. Signed-off-by: David Jeffery Signed-off-by: David Howells Signed-off-by: James Morris diff --git a/security/keys/request_key.c b/security/keys/request_key.c index 0c7aea4..486ef6f 100644 --- a/security/keys/request_key.c +++ b/security/keys/request_key.c @@ -414,6 +414,7 @@ link_check_failed: link_prealloc_failed: mutex_unlock(&user->cons_lock); + key_put(key); kleave(" = %d [prelink]", ret); return ret; -- cgit v0.10.2