1
0
Fork 0

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
alistair/sunxi64-5.5-dsi
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) if (ret < 0)
goto error_free_tfm; goto error_free_tfm;
ret = -ENOMEM;
req = akcipher_request_alloc(tfm, GFP_KERNEL); req = akcipher_request_alloc(tfm, GFP_KERNEL);
if (!req) if (!req)
goto error_free_tfm; 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)) if (IS_ERR(tfm))
return PTR_ERR(tfm); return PTR_ERR(tfm);
ret = -ENOMEM;
req = akcipher_request_alloc(tfm, GFP_KERNEL); req = akcipher_request_alloc(tfm, GFP_KERNEL);
if (!req) if (!req)
goto error_free_tfm; 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); mutex_lock(&priv->buffer_mutex);
priv->command_enqueued = false; 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, ret = tpm_dev_transmit(priv->chip, priv->space, priv->data_buffer,
sizeof(priv->data_buffer)); sizeof(priv->data_buffer));
tpm_put_ops(priv->chip); tpm_put_ops(priv->chip);
@ -68,6 +74,7 @@ static void tpm_dev_async_work(struct work_struct *work)
priv->response_length = ret; priv->response_length = ret;
mod_timer(&priv->user_read_timer, jiffies + (120 * HZ)); mod_timer(&priv->user_read_timer, jiffies + (120 * HZ));
} }
out:
mutex_unlock(&priv->buffer_mutex); mutex_unlock(&priv->buffer_mutex);
wake_up_interruptible(&priv->async_wait); 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) { if (file->f_flags & O_NONBLOCK) {
priv->command_enqueued = true; priv->command_enqueued = true;
queue_work(tpm_dev_wq, &priv->async_work); queue_work(tpm_dev_wq, &priv->async_work);
tpm_put_ops(priv->chip);
mutex_unlock(&priv->buffer_mutex); mutex_unlock(&priv->buffer_mutex);
return size; 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, int tpm2_pcr_extend(struct tpm_chip *chip, u32 pcr_idx,
struct tpm_digest *digests); struct tpm_digest *digests);
int tpm2_get_random(struct tpm_chip *chip, u8 *dest, size_t max); 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, ssize_t tpm2_get_tpm_pt(struct tpm_chip *chip, u32 property_id,
u32 *value, const char *desc); 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_transmit_cmd(chip, &buf, 0, "flushing context");
tpm_buf_destroy(&buf); tpm_buf_destroy(&buf);
} }
EXPORT_SYMBOL_GPL(tpm2_flush_context);
struct tpm2_get_cap_out { struct tpm2_get_cap_out {
u8 more_data; u8 more_data;

View File

@ -32,7 +32,7 @@ static const uuid_t ftpm_ta_uuid =
0x82, 0xCB, 0x34, 0x3F, 0xB7, 0xF3, 0x78, 0x96); 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. * @chip: the tpm_chip description as specified in driver/char/tpm/tpm.h.
* @buf: the buffer to store data. * @buf: the buffer to store data.
* @count: the number of bytes to read. * @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 * @chip: the tpm_chip description as specified in driver/char/tpm/tpm.h
* @buf: the buffer to send. * @buf: the buffer to send.
* @len: the number of bytes 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. * @pdev: the platform_device description.
* *
* Return: * Return:
@ -298,7 +298,7 @@ out_tee_session:
} }
/** /**
* ftpm_tee_remove - remove the TPM device * ftpm_tee_remove() - remove the TPM device
* @pdev: the platform_device description. * @pdev: the platform_device description.
* *
* Return: * Return:
@ -328,6 +328,19 @@ static int ftpm_tee_remove(struct platform_device *pdev)
return 0; 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[] = { static const struct of_device_id of_ftpm_tee_ids[] = {
{ .compatible = "microsoft,ftpm" }, { .compatible = "microsoft,ftpm" },
{ } { }
@ -341,6 +354,7 @@ static struct platform_driver ftpm_tee_driver = {
}, },
.probe = ftpm_tee_probe, .probe = ftpm_tee_probe,
.remove = ftpm_tee_remove, .remove = ftpm_tee_remove,
.shutdown = ftpm_tee_shutdown,
}; };
module_platform_driver(ftpm_tee_driver); 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) { if (wait_startup(chip, 0) != 0) {
rc = -ENODEV; rc = -ENODEV;
goto out_err; goto err_start;
} }
/* Take control of the TPM's interrupt hardware and shut it off */ /* Take control of the TPM's interrupt hardware and shut it off */
rc = tpm_tis_read32(priv, TPM_INT_ENABLE(priv->locality), &intmask); rc = tpm_tis_read32(priv, TPM_INT_ENABLE(priv->locality), &intmask);
if (rc < 0) if (rc < 0)
goto out_err; goto err_start;
intmask |= TPM_INTF_CMD_READY_INT | TPM_INTF_LOCALITY_CHANGE_INT | intmask |= TPM_INTF_CMD_READY_INT | TPM_INTF_LOCALITY_CHANGE_INT |
TPM_INTF_DATA_AVAIL_INT | TPM_INTF_STS_VALID_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); rc = tpm_chip_start(chip);
if (rc) if (rc)
goto out_err; goto err_start;
rc = tpm2_probe(chip); rc = tpm2_probe(chip);
tpm_chip_stop(chip);
if (rc) if (rc)
goto out_err; goto err_probe;
rc = tpm_tis_read32(priv, TPM_DID_VID(0), &vendor); rc = tpm_tis_read32(priv, TPM_DID_VID(0), &vendor);
if (rc < 0) if (rc < 0)
goto out_err; goto err_probe;
priv->manufacturer_id = vendor; priv->manufacturer_id = vendor;
rc = tpm_tis_read8(priv, TPM_RID(0), &rid); rc = tpm_tis_read8(priv, TPM_RID(0), &rid);
if (rc < 0) if (rc < 0)
goto out_err; goto err_probe;
dev_info(dev, "%s TPM (device-id 0x%X, rev-id %d)\n", dev_info(dev, "%s TPM (device-id 0x%X, rev-id %d)\n",
(chip->flags & TPM_CHIP_FLAG_TPM2) ? "2.0" : "1.2", (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); probe = probe_itpm(chip);
if (probe < 0) { if (probe < 0) {
rc = -ENODEV; rc = -ENODEV;
goto out_err; goto err_probe;
} }
/* Figure out the capabilities */ /* Figure out the capabilities */
rc = tpm_tis_read32(priv, TPM_INTF_CAPS(priv->locality), &intfcaps); rc = tpm_tis_read32(priv, TPM_INTF_CAPS(priv->locality), &intfcaps);
if (rc < 0) if (rc < 0)
goto out_err; goto err_probe;
dev_dbg(dev, "TPM interface capabilities (0x%x):\n", dev_dbg(dev, "TPM interface capabilities (0x%x):\n",
intfcaps); 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)) { if (tpm_get_timeouts(chip)) {
dev_err(dev, "Could not get TPM timeouts and durations\n"); dev_err(dev, "Could not get TPM timeouts and durations\n");
rc = -ENODEV; rc = -ENODEV;
goto out_err; goto err_probe;
} }
tpm_chip_start(chip);
chip->flags |= TPM_CHIP_FLAG_IRQ; chip->flags |= TPM_CHIP_FLAG_IRQ;
if (irq) { if (irq) {
tpm_tis_probe_irq_single(chip, intmask, IRQF_SHARED, 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 { } else {
tpm_tis_probe_irq(chip, intmask); tpm_tis_probe_irq(chip, intmask);
} }
tpm_chip_stop(chip);
} }
tpm_chip_stop(chip);
rc = tpm_chip_register(chip); rc = tpm_chip_register(chip);
if (rc) if (rc)
goto out_err; goto err_start;
if (chip->ops->clk_enable != NULL)
chip->ops->clk_enable(chip, false);
return 0; return 0;
out_err:
err_probe:
tpm_chip_stop(chip);
err_start:
if ((chip->ops != NULL) && (chip->ops->clk_enable != NULL)) if ((chip->ops != NULL) && (chip->ops->clk_enable != NULL))
chip->ops->clk_enable(chip, false); 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_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 int tpm_get_random(struct tpm_chip *chip, u8 *data, size_t max);
extern struct tpm_chip *tpm_default_chip(void); extern struct tpm_chip *tpm_default_chip(void);
void tpm2_flush_context(struct tpm_chip *chip, u32 handle);
#else #else
static inline int tpm_is_tpm2(struct tpm_chip *chip) 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. 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 config KEYS_REQUEST_CACHE
bool "Enable temporary caching of the last request_key() result" bool "Enable temporary caching of the last request_key() result"
depends on KEYS depends on KEYS

View File

@ -17,7 +17,7 @@ obj-y := \
request_key_auth.o \ request_key_auth.o \
user_defined.o user_defined.o
compat-obj-$(CONFIG_KEY_DH_OPERATIONS) += compat_dh.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_PROC_FS) += proc.o
obj-$(CONFIG_SYSCTL) += sysctl.o obj-$(CONFIG_SYSCTL) += sysctl.o
obj-$(CONFIG_PERSISTENT_KEYRINGS) += persistent.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 * 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, COMPAT_SYSCALL_DEFINE5(keyctl, u32, option,
u32, arg2, u32, arg3, u32, arg4, u32, arg5) 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 *); size_t, struct keyctl_kdf_params __user *);
extern long __keyctl_dh_compute(struct keyctl_dh_params __user *, char __user *, extern long __keyctl_dh_compute(struct keyctl_dh_params __user *, char __user *,
size_t, struct keyctl_kdf_params *); 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, extern long compat_keyctl_dh_compute(struct keyctl_dh_params __user *params,
char __user *buffer, size_t buflen, char __user *buffer, size_t buflen,
struct compat_keyctl_kdf_params __user *kdf); 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; return -EOPNOTSUPP;
} }
#ifdef CONFIG_KEYS_COMPAT #ifdef CONFIG_COMPAT
static inline long compat_keyctl_dh_compute( static inline long compat_keyctl_dh_compute(
struct keyctl_dh_params __user *params, struct keyctl_dh_params __user *params,
char __user *buffer, size_t buflen, char __user *buffer, size_t buflen,

View File

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

View File

@ -2,3 +2,9 @@
# SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause) # SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause)
python -m unittest -v tpm2_tests.SmokeTest 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 struct
import sys import sys
import unittest import unittest
from fcntl import ioctl import fcntl
import select
TPM2_ST_NO_SESSIONS = 0x8001 TPM2_ST_NO_SESSIONS = 0x8001
TPM2_ST_SESSIONS = 0x8002 TPM2_ST_SESSIONS = 0x8002
@ -352,6 +352,7 @@ def hex_dump(d):
class Client: class Client:
FLAG_DEBUG = 0x01 FLAG_DEBUG = 0x01
FLAG_SPACE = 0x02 FLAG_SPACE = 0x02
FLAG_NONBLOCK = 0x04
TPM_IOC_NEW_SPACE = 0xa200 TPM_IOC_NEW_SPACE = 0xa200
def __init__(self, flags = 0): def __init__(self, flags = 0):
@ -362,13 +363,27 @@ class Client:
else: else:
self.tpm = open('/dev/tpmrm0', 'r+b', buffering=0) 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): def close(self):
self.tpm.close() self.tpm.close()
def send_cmd(self, cmd): def send_cmd(self, cmd):
self.tpm.write(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() rsp = self.tpm.read()
if (self.flags & Client.FLAG_NONBLOCK):
self.tpm_poll.unregister(self.tpm)
if (self.flags & Client.FLAG_DEBUG) != 0: if (self.flags & Client.FLAG_DEBUG) != 0:
sys.stderr.write('cmd' + os.linesep) sys.stderr.write('cmd' + os.linesep)
sys.stderr.write(hex_dump(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 | self.assertEqual(rc, tpm2.TPM2_RC_COMMAND_CODE |
tpm2.TSS2_RESMGR_TPM_RC_LAYER) 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()