Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 1d9e7140 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
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
parents cc4f9c2a 0d309cbd
Loading
Loading
Loading
Loading
+4 −2
Original line number Original line Diff line number Diff line
@@ -901,8 +901,10 @@ int tpm_pm_suspend(struct device *dev)
	if (chip == NULL)
	if (chip == NULL)
		return -ENODEV;
		return -ENODEV;


	if (chip->flags & TPM_CHIP_FLAG_TPM2)
	if (chip->flags & TPM_CHIP_FLAG_TPM2) {
		return tpm2_shutdown(chip, TPM2_SU_CLEAR);
		tpm2_shutdown(chip, TPM2_SU_STATE);
		return 0;
	}


	/* for buggy tpm, flush pcrs with extend to selected dummy */
	/* for buggy tpm, flush pcrs with extend to selected dummy */
	if (tpm_suspend_pcr) {
	if (tpm_suspend_pcr) {
+3 −2
Original line number Original line Diff line number Diff line
@@ -432,7 +432,8 @@ ssize_t tpm2_get_tpm_pt(struct tpm_chip *chip, u32 property_id,
			u32 *value, const char *desc);
			u32 *value, const char *desc);


extern int tpm2_startup(struct tpm_chip *chip, u16 startup_type);
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 unsigned long tpm2_calc_ordinal_duration(struct tpm_chip *, u32);
extern int tpm2_do_selftest(struct tpm_chip *chip);
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);
+44 −15
Original line number Original line Diff line number Diff line
@@ -456,20 +456,23 @@ static const struct tpm_input_header tpm2_shutdown_header = {
 * @chip:		TPM chip to use.
 * @chip:		TPM chip to use.
 * @shutdown_type	shutdown type. The value is either
 * @shutdown_type	shutdown type. The value is either
 *			TPM_SU_CLEAR or TPM_SU_STATE.
 *			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;
	struct tpm2_cmd cmd;
	int rc;


	cmd.header.in = tpm2_shutdown_header;
	cmd.header.in = tpm2_shutdown_header;

	cmd.params.startup_in.startup_type = cpu_to_be16(shutdown_type);
	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);
EXPORT_SYMBOL_GPL(tpm2_shutdown);


@@ -598,20 +601,46 @@ EXPORT_SYMBOL_GPL(tpm2_do_selftest);
/**
/**
 * tpm2_gen_interrupt() - generate an interrupt
 * tpm2_gen_interrupt() - generate an interrupt
 * @chip: TPM chip to use
 * @chip: TPM chip to use
 * @quiet: surpress the error message
 *
 *
 * 0 is returned when the operation is successful. If a negative number is
 * 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
 * returned it remarks a POSIX error code. If a positive number is returned
 * it remarks a TPM error.
 * 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;
	u32 dummy;


	if (!quiet)
	return tpm2_get_tpm_pt(chip, 0x100, &dummy,
		desc = "attempting to generate an interrupt";
			       "attempting to generate an interrupt");

	return tpm2_get_tpm_pt(chip, TPM2_CAP_TPM_PROPERTIES, &dummy, desc);
}
}
EXPORT_SYMBOL_GPL(tpm2_gen_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);
+5 −15
Original line number Original line Diff line number Diff line
@@ -95,21 +95,7 @@ struct crb_priv {
	u8 __iomem *rsp;
	u8 __iomem *rsp;
};
};


#ifdef CONFIG_PM_SLEEP
static SIMPLE_DEV_PM_OPS(crb_pm, tpm_pm_suspend, tpm_pm_resume);
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 u8 crb_status(struct tpm_chip *chip)
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);
	struct tpm_chip *chip = dev_get_drvdata(dev);


	tpm_chip_unregister(chip);
	tpm_chip_unregister(chip);

	if (chip->flags & TPM_CHIP_FLAG_TPM2)
		tpm2_shutdown(chip, TPM2_SU_CLEAR);

	return 0;
	return 0;
}
}


+12 −8
Original line number Original line Diff line number Diff line
@@ -148,7 +148,8 @@ static int tpm_ibmvtpm_send(struct tpm_chip *chip, u8 *buf, size_t count)
	crq.len = (u16)count;
	crq.len = (u16)count;
	crq.data = ibmvtpm->rtce_dma_handle;
	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) {
	if (rc != H_SUCCESS) {
		dev_err(ibmvtpm->dev, "tpm_ibmvtpm_send failed rc=%d\n", rc);
		dev_err(ibmvtpm->dev, "tpm_ibmvtpm_send failed rc=%d\n", rc);
		rc = 0;
		rc = 0;
@@ -186,7 +187,8 @@ static int ibmvtpm_crq_get_rtce_size(struct ibmvtpm_dev *ibmvtpm)
	crq.valid = (u8)IBMVTPM_VALID_CMD;
	crq.valid = (u8)IBMVTPM_VALID_CMD;
	crq.msg = (u8)VTPM_GET_RTCE_BUFFER_SIZE;
	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)
	if (rc != H_SUCCESS)
		dev_err(ibmvtpm->dev,
		dev_err(ibmvtpm->dev,
			"ibmvtpm_crq_get_rtce_size failed rc=%d\n", rc);
			"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.valid = (u8)IBMVTPM_VALID_CMD;
	crq.msg = (u8)VTPM_GET_VERSION;
	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)
	if (rc != H_SUCCESS)
		dev_err(ibmvtpm->dev,
		dev_err(ibmvtpm->dev,
			"ibmvtpm_crq_get_version failed rc=%d\n", rc);
			"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.valid = (u8)IBMVTPM_VALID_CMD;
	crq.msg = (u8)VTPM_PREPARE_TO_SUSPEND;
	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)
	if (rc != H_SUCCESS)
		dev_err(ibmvtpm->dev,
		dev_err(ibmvtpm->dev,
			"tpm_ibmvtpm_suspend failed rc=%d\n", rc);
			"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:
	case IBMVTPM_VALID_CMD:
		switch (crq->msg) {
		switch (crq->msg) {
		case VTPM_GET_RTCE_BUFFER_SIZE_RES:
		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");
				dev_err(ibmvtpm->dev, "Invalid rtce size\n");
				return;
				return;
			}
			}
			ibmvtpm->rtce_size = crq->len;
			ibmvtpm->rtce_size = be16_to_cpu(crq->len);
			ibmvtpm->rtce_buf = kmalloc(ibmvtpm->rtce_size,
			ibmvtpm->rtce_buf = kmalloc(ibmvtpm->rtce_size,
						    GFP_KERNEL);
						    GFP_KERNEL);
			if (!ibmvtpm->rtce_buf) {
			if (!ibmvtpm->rtce_buf) {
@@ -506,11 +510,11 @@ static void ibmvtpm_crq_process(struct ibmvtpm_crq *crq,


			return;
			return;
		case VTPM_GET_VERSION_RES:
		case VTPM_GET_VERSION_RES:
			ibmvtpm->vtpm_version = crq->data;
			ibmvtpm->vtpm_version = be32_to_cpu(crq->data);
			return;
			return;
		case VTPM_TPM_COMMAND_RES:
		case VTPM_TPM_COMMAND_RES:
			/* len of the data in rtce buffer */
			/* 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);
			wake_up_interruptible(&ibmvtpm->wq);
			return;
			return;
		default:
		default:
Loading