Skip to content

Commit

Permalink
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel…
Browse files Browse the repository at this point in the history
…/git/jmorris/linux-security

Pull security subsystem fixes from James Morris.

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/linux-security:
  Don't leak a key reference if request_key() tries to use a revoked keyring
  Added Little Endian support to vtpm module
  tpm, tpm_tis: fix TPM 2.0 probing
  tpm: fix suspend/resume paths for TPM 2.0
  Smack: secmark connections
  • Loading branch information
Linus Torvalds committed Feb 17, 2015
2 parents cc4f9c2 + 0d309cb commit 1d9e714
Show file tree
Hide file tree
Showing 8 changed files with 102 additions and 62 deletions.
6 changes: 4 additions & 2 deletions drivers/char/tpm/tpm-interface.c
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
5 changes: 3 additions & 2 deletions drivers/char/tpm/tpm.h
Original file line number Diff line number Diff line change
Expand Up @@ -432,7 +432,8 @@ 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);
extern int tpm2_gen_interrupt(struct tpm_chip *chip);
extern int tpm2_probe(struct tpm_chip *chip);
59 changes: 44 additions & 15 deletions drivers/char/tpm/tpm2-cmd.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down Expand Up @@ -598,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);
20 changes: 5 additions & 15 deletions drivers/char/tpm/tpm_crb.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
Expand Down Expand Up @@ -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;
}

Expand Down
20 changes: 12 additions & 8 deletions drivers/char/tpm/tpm_ibmvtpm.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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);
Expand All @@ -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);
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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) {
Expand All @@ -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:
Expand Down
37 changes: 17 additions & 20 deletions drivers/char/tpm/tpm_tis.c
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -639,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;
Expand Down Expand Up @@ -747,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);

Expand Down Expand Up @@ -865,25 +865,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

Expand Down
1 change: 1 addition & 0 deletions security/keys/request_key.c
Original file line number Diff line number Diff line change
Expand Up @@ -414,6 +414,7 @@ static int construct_alloc_key(struct keyring_search_context *ctx,

link_prealloc_failed:
mutex_unlock(&user->cons_lock);
key_put(key);
kleave(" = %d [prelink]", ret);
return ret;

Expand Down
16 changes: 16 additions & 0 deletions security/smack/smack_lsm.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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;
Expand Down

0 comments on commit 1d9e714

Please sign in to comment.