tpmdd fixes for Linux v5.5-rc3

-----BEGIN PGP SIGNATURE-----
 
 iJYEABYIAD4WIQRE6pSOnaBC00OEHEIaerohdGur0gUCXfrLASAcamFya2tvLnNh
 a2tpbmVuQGxpbnV4LmludGVsLmNvbQAKCRAaerohdGur0pZfAQD9F5Vjdqp3fWk+
 pxt+eD9+xaD2MYuSVO2AEVBC949vdQD/TP7xnb66w7n9YtMtm9MgvysHAakJYeAe
 l4XsHAiPHgI=
 =CFIs
 -----END PGP SIGNATURE-----

Merge tag 'tpmdd-next-20191219' of git://git.infradead.org/users/jjs/linux-tpmdd

Pull tpm fixes from Jarkko Sakkinen:
 "Bunch of fixes for rc3"

* tag 'tpmdd-next-20191219' of git://git.infradead.org/users/jjs/linux-tpmdd:
  tpm/tpm_ftpm_tee: add shutdown call back
  tpm: selftest: cleanup after unseal with wrong auth/policy test
  tpm: selftest: add test covering async mode
  tpm: fix invalid locking in NONBLOCKING mode
  security: keys: trusted: fix lost handle flush
  tpm_tis: reserve chip for duration of tpm_tis_core_init
  KEYS: asymmetric: return ENOMEM if akcipher_request_alloc() fails
  KEYS: remove CONFIG_KEYS_COMPAT
This commit is contained in:
Linus Torvalds 2019-12-18 17:17:36 -08:00
commit 4a94c43323
16 changed files with 88 additions and 36 deletions

View File

@ -470,6 +470,7 @@ static int tpm_key_encrypt(struct tpm_key *tk,
if (ret < 0)
goto error_free_tfm;
ret = -ENOMEM;
req = akcipher_request_alloc(tfm, GFP_KERNEL);
if (!req)
goto error_free_tfm;

View File

@ -184,6 +184,7 @@ static int software_key_eds_op(struct kernel_pkey_params *params,
if (IS_ERR(tfm))
return PTR_ERR(tfm);
ret = -ENOMEM;
req = akcipher_request_alloc(tfm, GFP_KERNEL);
if (!req)
goto error_free_tfm;

View File

@ -61,6 +61,12 @@ static void tpm_dev_async_work(struct work_struct *work)
mutex_lock(&priv->buffer_mutex);
priv->command_enqueued = false;
ret = tpm_try_get_ops(priv->chip);
if (ret) {
priv->response_length = ret;
goto out;
}
ret = tpm_dev_transmit(priv->chip, priv->space, priv->data_buffer,
sizeof(priv->data_buffer));
tpm_put_ops(priv->chip);
@ -68,6 +74,7 @@ static void tpm_dev_async_work(struct work_struct *work)
priv->response_length = ret;
mod_timer(&priv->user_read_timer, jiffies + (120 * HZ));
}
out:
mutex_unlock(&priv->buffer_mutex);
wake_up_interruptible(&priv->async_wait);
}
@ -204,6 +211,7 @@ ssize_t tpm_common_write(struct file *file, const char __user *buf,
if (file->f_flags & O_NONBLOCK) {
priv->command_enqueued = true;
queue_work(tpm_dev_wq, &priv->async_work);
tpm_put_ops(priv->chip);
mutex_unlock(&priv->buffer_mutex);
return size;
}

View File

@ -218,7 +218,6 @@ int tpm2_pcr_read(struct tpm_chip *chip, u32 pcr_idx,
int tpm2_pcr_extend(struct tpm_chip *chip, u32 pcr_idx,
struct tpm_digest *digests);
int tpm2_get_random(struct tpm_chip *chip, u8 *dest, size_t max);
void tpm2_flush_context(struct tpm_chip *chip, u32 handle);
ssize_t tpm2_get_tpm_pt(struct tpm_chip *chip, u32 property_id,
u32 *value, const char *desc);

View File

@ -362,6 +362,7 @@ void tpm2_flush_context(struct tpm_chip *chip, u32 handle)
tpm_transmit_cmd(chip, &buf, 0, "flushing context");
tpm_buf_destroy(&buf);
}
EXPORT_SYMBOL_GPL(tpm2_flush_context);
struct tpm2_get_cap_out {
u8 more_data;

View File

@ -32,7 +32,7 @@ static const uuid_t ftpm_ta_uuid =
0x82, 0xCB, 0x34, 0x3F, 0xB7, 0xF3, 0x78, 0x96);
/**
* ftpm_tee_tpm_op_recv - retrieve fTPM response.
* ftpm_tee_tpm_op_recv() - retrieve fTPM response.
* @chip: the tpm_chip description as specified in driver/char/tpm/tpm.h.
* @buf: the buffer to store data.
* @count: the number of bytes to read.
@ -61,7 +61,7 @@ static int ftpm_tee_tpm_op_recv(struct tpm_chip *chip, u8 *buf, size_t count)
}
/**
* ftpm_tee_tpm_op_send - send TPM commands through the TEE shared memory.
* ftpm_tee_tpm_op_send() - send TPM commands through the TEE shared memory.
* @chip: the tpm_chip description as specified in driver/char/tpm/tpm.h
* @buf: the buffer to send.
* @len: the number of bytes to send.
@ -208,7 +208,7 @@ static int ftpm_tee_match(struct tee_ioctl_version_data *ver, const void *data)
}
/**
* ftpm_tee_probe - initialize the fTPM
* ftpm_tee_probe() - initialize the fTPM
* @pdev: the platform_device description.
*
* Return:
@ -298,7 +298,7 @@ static int ftpm_tee_probe(struct platform_device *pdev)
}
/**
* ftpm_tee_remove - remove the TPM device
* ftpm_tee_remove() - remove the TPM device
* @pdev: the platform_device description.
*
* Return:
@ -328,6 +328,19 @@ static int ftpm_tee_remove(struct platform_device *pdev)
return 0;
}
/**
* ftpm_tee_shutdown() - shutdown the TPM device
* @pdev: the platform_device description.
*/
static void ftpm_tee_shutdown(struct platform_device *pdev)
{
struct ftpm_tee_private *pvt_data = dev_get_drvdata(&pdev->dev);
tee_shm_free(pvt_data->shm);
tee_client_close_session(pvt_data->ctx, pvt_data->session);
tee_client_close_context(pvt_data->ctx);
}
static const struct of_device_id of_ftpm_tee_ids[] = {
{ .compatible = "microsoft,ftpm" },
{ }
@ -341,6 +354,7 @@ static struct platform_driver ftpm_tee_driver = {
},
.probe = ftpm_tee_probe,
.remove = ftpm_tee_remove,
.shutdown = ftpm_tee_shutdown,
};
module_platform_driver(ftpm_tee_driver);

View File

@ -978,13 +978,13 @@ int tpm_tis_core_init(struct device *dev, struct tpm_tis_data *priv, int irq,
if (wait_startup(chip, 0) != 0) {
rc = -ENODEV;
goto out_err;
goto err_start;
}
/* Take control of the TPM's interrupt hardware and shut it off */
rc = tpm_tis_read32(priv, TPM_INT_ENABLE(priv->locality), &intmask);
if (rc < 0)
goto out_err;
goto err_start;
intmask |= TPM_INTF_CMD_READY_INT | TPM_INTF_LOCALITY_CHANGE_INT |
TPM_INTF_DATA_AVAIL_INT | TPM_INTF_STS_VALID_INT;
@ -993,21 +993,21 @@ int tpm_tis_core_init(struct device *dev, struct tpm_tis_data *priv, int irq,
rc = tpm_chip_start(chip);
if (rc)
goto out_err;
goto err_start;
rc = tpm2_probe(chip);
tpm_chip_stop(chip);
if (rc)
goto out_err;
goto err_probe;
rc = tpm_tis_read32(priv, TPM_DID_VID(0), &vendor);
if (rc < 0)
goto out_err;
goto err_probe;
priv->manufacturer_id = vendor;
rc = tpm_tis_read8(priv, TPM_RID(0), &rid);
if (rc < 0)
goto out_err;
goto err_probe;
dev_info(dev, "%s TPM (device-id 0x%X, rev-id %d)\n",
(chip->flags & TPM_CHIP_FLAG_TPM2) ? "2.0" : "1.2",
@ -1016,13 +1016,13 @@ int tpm_tis_core_init(struct device *dev, struct tpm_tis_data *priv, int irq,
probe = probe_itpm(chip);
if (probe < 0) {
rc = -ENODEV;
goto out_err;
goto err_probe;
}
/* Figure out the capabilities */
rc = tpm_tis_read32(priv, TPM_INTF_CAPS(priv->locality), &intfcaps);
if (rc < 0)
goto out_err;
goto err_probe;
dev_dbg(dev, "TPM interface capabilities (0x%x):\n",
intfcaps);
@ -1056,10 +1056,9 @@ int tpm_tis_core_init(struct device *dev, struct tpm_tis_data *priv, int irq,
if (tpm_get_timeouts(chip)) {
dev_err(dev, "Could not get TPM timeouts and durations\n");
rc = -ENODEV;
goto out_err;
goto err_probe;
}
tpm_chip_start(chip);
chip->flags |= TPM_CHIP_FLAG_IRQ;
if (irq) {
tpm_tis_probe_irq_single(chip, intmask, IRQF_SHARED,
@ -1070,18 +1069,20 @@ int tpm_tis_core_init(struct device *dev, struct tpm_tis_data *priv, int irq,
} else {
tpm_tis_probe_irq(chip, intmask);
}
tpm_chip_stop(chip);
}
tpm_chip_stop(chip);
rc = tpm_chip_register(chip);
if (rc)
goto out_err;
if (chip->ops->clk_enable != NULL)
chip->ops->clk_enable(chip, false);
goto err_start;
return 0;
out_err:
err_probe:
tpm_chip_stop(chip);
err_start:
if ((chip->ops != NULL) && (chip->ops->clk_enable != NULL))
chip->ops->clk_enable(chip, false);

View File

@ -403,6 +403,7 @@ extern int tpm_pcr_extend(struct tpm_chip *chip, u32 pcr_idx,
extern int tpm_send(struct tpm_chip *chip, void *cmd, size_t buflen);
extern int tpm_get_random(struct tpm_chip *chip, u8 *data, size_t max);
extern struct tpm_chip *tpm_default_chip(void);
void tpm2_flush_context(struct tpm_chip *chip, u32 handle);
#else
static inline int tpm_is_tpm2(struct tpm_chip *chip)
{

View File

@ -21,10 +21,6 @@ config KEYS
If you are unsure as to whether this is required, answer N.
config KEYS_COMPAT
def_bool y
depends on COMPAT && KEYS
config KEYS_REQUEST_CACHE
bool "Enable temporary caching of the last request_key() result"
depends on KEYS

View File

@ -17,7 +17,7 @@ obj-y := \
request_key_auth.o \
user_defined.o
compat-obj-$(CONFIG_KEY_DH_OPERATIONS) += compat_dh.o
obj-$(CONFIG_KEYS_COMPAT) += compat.o $(compat-obj-y)
obj-$(CONFIG_COMPAT) += compat.o $(compat-obj-y)
obj-$(CONFIG_PROC_FS) += proc.o
obj-$(CONFIG_SYSCTL) += sysctl.o
obj-$(CONFIG_PERSISTENT_KEYRINGS) += persistent.o

View File

@ -46,11 +46,6 @@ static long compat_keyctl_instantiate_key_iov(
/*
* The key control system call, 32-bit compatibility version for 64-bit archs
*
* This should only be called if the 64-bit arch uses weird pointers in 32-bit
* mode or doesn't guarantee that the top 32-bits of the argument registers on
* taking a 32-bit syscall are zero. If you can, you should call sys_keyctl()
* directly.
*/
COMPAT_SYSCALL_DEFINE5(keyctl, u32, option,
u32, arg2, u32, arg3, u32, arg4, u32, arg5)

View File

@ -264,7 +264,7 @@ extern long keyctl_dh_compute(struct keyctl_dh_params __user *, char __user *,
size_t, struct keyctl_kdf_params __user *);
extern long __keyctl_dh_compute(struct keyctl_dh_params __user *, char __user *,
size_t, struct keyctl_kdf_params *);
#ifdef CONFIG_KEYS_COMPAT
#ifdef CONFIG_COMPAT
extern long compat_keyctl_dh_compute(struct keyctl_dh_params __user *params,
char __user *buffer, size_t buflen,
struct compat_keyctl_kdf_params __user *kdf);
@ -279,7 +279,7 @@ static inline long keyctl_dh_compute(struct keyctl_dh_params __user *params,
return -EOPNOTSUPP;
}
#ifdef CONFIG_KEYS_COMPAT
#ifdef CONFIG_COMPAT
static inline long compat_keyctl_dh_compute(
struct keyctl_dh_params __user *params,
char __user *buffer, size_t buflen,

View File

@ -309,6 +309,7 @@ int tpm2_unseal_trusted(struct tpm_chip *chip,
return rc;
rc = tpm2_unseal_cmd(chip, payload, options, blob_handle);
tpm2_flush_context(chip, blob_handle);
return rc;
}

View File

@ -2,3 +2,9 @@
# SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause)
python -m unittest -v tpm2_tests.SmokeTest
python -m unittest -v tpm2_tests.AsyncTest
CLEAR_CMD=$(which tpm2_clear)
if [ -n $CLEAR_CMD ]; then
tpm2_clear -T device
fi

View File

@ -6,8 +6,8 @@ import socket
import struct
import sys
import unittest
from fcntl import ioctl
import fcntl
import select
TPM2_ST_NO_SESSIONS = 0x8001
TPM2_ST_SESSIONS = 0x8002
@ -352,6 +352,7 @@ def hex_dump(d):
class Client:
FLAG_DEBUG = 0x01
FLAG_SPACE = 0x02
FLAG_NONBLOCK = 0x04
TPM_IOC_NEW_SPACE = 0xa200
def __init__(self, flags = 0):
@ -362,13 +363,27 @@ class Client:
else:
self.tpm = open('/dev/tpmrm0', 'r+b', buffering=0)
if (self.flags & Client.FLAG_NONBLOCK):
flags = fcntl.fcntl(self.tpm, fcntl.F_GETFL)
flags |= os.O_NONBLOCK
fcntl.fcntl(self.tpm, fcntl.F_SETFL, flags)
self.tpm_poll = select.poll()
def close(self):
self.tpm.close()
def send_cmd(self, cmd):
self.tpm.write(cmd)
if (self.flags & Client.FLAG_NONBLOCK):
self.tpm_poll.register(self.tpm, select.POLLIN)
self.tpm_poll.poll(10000)
rsp = self.tpm.read()
if (self.flags & Client.FLAG_NONBLOCK):
self.tpm_poll.unregister(self.tpm)
if (self.flags & Client.FLAG_DEBUG) != 0:
sys.stderr.write('cmd' + os.linesep)
sys.stderr.write(hex_dump(cmd) + os.linesep)

View File

@ -288,3 +288,16 @@ class SpaceTest(unittest.TestCase):
self.assertEqual(rc, tpm2.TPM2_RC_COMMAND_CODE |
tpm2.TSS2_RESMGR_TPM_RC_LAYER)
class AsyncTest(unittest.TestCase):
def setUp(self):
logging.basicConfig(filename='AsyncTest.log', level=logging.DEBUG)
def test_async(self):
log = logging.getLogger(__name__)
log.debug(sys._getframe().f_code.co_name)
async_client = tpm2.Client(tpm2.Client.FLAG_NONBLOCK)
log.debug("Calling get_cap in a NON_BLOCKING mode")
async_client.get_cap(tpm2.TPM2_CAP_HANDLES, tpm2.HR_LOADED_SESSION)
async_client.close()