Skip to content

Commit

Permalink
Merge tag 'tpmdd-next-20191219' of git://git.infradead.org/users/jjs/…
Browse files Browse the repository at this point in the history
…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
  • Loading branch information
Linus Torvalds committed Dec 19, 2019
2 parents 80a0c2e + 1760eb6 commit 4a94c43
Show file tree
Hide file tree
Showing 16 changed files with 88 additions and 36 deletions.
1 change: 1 addition & 0 deletions crypto/asymmetric_keys/asym_tpm.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
1 change: 1 addition & 0 deletions crypto/asymmetric_keys/public_key.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
8 changes: 8 additions & 0 deletions drivers/char/tpm/tpm-dev-common.c
Original file line number Diff line number Diff line change
Expand Up @@ -61,13 +61,20 @@ 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);
if (ret > 0) {
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);
}
Expand Down Expand Up @@ -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;
}
Expand Down
1 change: 0 additions & 1 deletion drivers/char/tpm/tpm.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down
1 change: 1 addition & 0 deletions drivers/char/tpm/tpm2-cmd.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
22 changes: 18 additions & 4 deletions drivers/char/tpm/tpm_ftpm_tee.c
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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:
Expand Down Expand Up @@ -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:
Expand Down Expand Up @@ -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" },
{ }
Expand All @@ -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);
Expand Down
35 changes: 18 additions & 17 deletions drivers/char/tpm/tpm_tis_core.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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",
Expand All @@ -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);
Expand Down Expand Up @@ -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,
Expand All @@ -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);

Expand Down
1 change: 1 addition & 0 deletions include/linux/tpm.h
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
Expand Down
4 changes: 0 additions & 4 deletions security/keys/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion security/keys/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
5 changes: 0 additions & 5 deletions security/keys/compat.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
4 changes: 2 additions & 2 deletions security/keys/internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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,
Expand Down
1 change: 1 addition & 0 deletions security/keys/trusted-keys/trusted_tpm2.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
6 changes: 6 additions & 0 deletions tools/testing/selftests/tpm2/test_smoke.sh
Original file line number Diff line number Diff line change
Expand Up @@ -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
19 changes: 17 additions & 2 deletions tools/testing/selftests/tpm2/tpm2.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@
import struct
import sys
import unittest
from fcntl import ioctl

import fcntl
import select

TPM2_ST_NO_SESSIONS = 0x8001
TPM2_ST_SESSIONS = 0x8002
Expand Down Expand Up @@ -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):
Expand All @@ -362,13 +363,27 @@ def __init__(self, flags = 0):
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)
Expand Down
13 changes: 13 additions & 0 deletions tools/testing/selftests/tpm2/tpm2_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -288,3 +288,16 @@ def test_invalid_cc(self):

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()

0 comments on commit 4a94c43

Please sign in to comment.