Skip to content

Commit a556810

Browse files
committed
Merge branch 'fixes-v5.1' of git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/linux-security
Pull TPM fixes from James Morris: "From Jarkko: These are critical fixes for v5.1. Contains also couple of new selftests for v5.1 features (partial reads in /dev/tpm0)" * 'fixes-v5.1' of git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/linux-security: selftests/tpm2: Open tpm dev in unbuffered mode selftests/tpm2: Extend tests to cover partial reads KEYS: trusted: fix -Wvarags warning tpm: Fix the type of the return value in calc_tpm2_event_size() KEYS: trusted: allow trusted.ko to initialize w/o a TPM tpm: fix an invalid condition in tpm_common_poll tpm: turn on TPM on suspend for TPM 1.x
2 parents 10d4339 + 6da7058 commit a556810

File tree

7 files changed

+108
-21
lines changed

7 files changed

+108
-21
lines changed

drivers/char/tpm/eventlog/tpm2.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,8 @@
3737
*
3838
* Returns size of the event. If it is an invalid event, returns 0.
3939
*/
40-
static int calc_tpm2_event_size(struct tcg_pcr_event2_head *event,
41-
struct tcg_pcr_event *event_header)
40+
static size_t calc_tpm2_event_size(struct tcg_pcr_event2_head *event,
41+
struct tcg_pcr_event *event_header)
4242
{
4343
struct tcg_efi_specid_event_head *efispecid;
4444
struct tcg_event_field *event_field;

drivers/char/tpm/tpm-dev-common.c

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -233,12 +233,19 @@ __poll_t tpm_common_poll(struct file *file, poll_table *wait)
233233
__poll_t mask = 0;
234234

235235
poll_wait(file, &priv->async_wait, wait);
236+
mutex_lock(&priv->buffer_mutex);
236237

237-
if (!priv->response_read || priv->response_length)
238+
/*
239+
* The response_length indicates if there is still response
240+
* (or part of it) to be consumed. Partial reads decrease it
241+
* by the number of bytes read, and write resets it the zero.
242+
*/
243+
if (priv->response_length)
238244
mask = EPOLLIN | EPOLLRDNORM;
239245
else
240246
mask = EPOLLOUT | EPOLLWRNORM;
241247

248+
mutex_unlock(&priv->buffer_mutex);
242249
return mask;
243250
}
244251

drivers/char/tpm/tpm-interface.c

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -402,15 +402,13 @@ int tpm_pm_suspend(struct device *dev)
402402
if (chip->flags & TPM_CHIP_FLAG_ALWAYS_POWERED)
403403
return 0;
404404

405-
if (chip->flags & TPM_CHIP_FLAG_TPM2) {
406-
mutex_lock(&chip->tpm_mutex);
407-
if (!tpm_chip_start(chip)) {
405+
if (!tpm_chip_start(chip)) {
406+
if (chip->flags & TPM_CHIP_FLAG_TPM2)
408407
tpm2_shutdown(chip, TPM2_SU_STATE);
409-
tpm_chip_stop(chip);
410-
}
411-
mutex_unlock(&chip->tpm_mutex);
412-
} else {
413-
rc = tpm1_pm_suspend(chip, tpm_suspend_pcr);
408+
else
409+
rc = tpm1_pm_suspend(chip, tpm_suspend_pcr);
410+
411+
tpm_chip_stop(chip);
414412
}
415413

416414
return rc;

include/keys/trusted.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ enum {
3838

3939
int TSS_authhmac(unsigned char *digest, const unsigned char *key,
4040
unsigned int keylen, unsigned char *h1,
41-
unsigned char *h2, unsigned char h3, ...);
41+
unsigned char *h2, unsigned int h3, ...);
4242
int TSS_checkhmac1(unsigned char *buffer,
4343
const uint32_t command,
4444
const unsigned char *ononce,

security/keys/trusted.c

Lines changed: 25 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ static int TSS_rawhmac(unsigned char *digest, const unsigned char *key,
125125
*/
126126
int TSS_authhmac(unsigned char *digest, const unsigned char *key,
127127
unsigned int keylen, unsigned char *h1,
128-
unsigned char *h2, unsigned char h3, ...)
128+
unsigned char *h2, unsigned int h3, ...)
129129
{
130130
unsigned char paramdigest[SHA1_DIGEST_SIZE];
131131
struct sdesc *sdesc;
@@ -135,13 +135,16 @@ int TSS_authhmac(unsigned char *digest, const unsigned char *key,
135135
int ret;
136136
va_list argp;
137137

138+
if (!chip)
139+
return -ENODEV;
140+
138141
sdesc = init_sdesc(hashalg);
139142
if (IS_ERR(sdesc)) {
140143
pr_info("trusted_key: can't alloc %s\n", hash_alg);
141144
return PTR_ERR(sdesc);
142145
}
143146

144-
c = h3;
147+
c = !!h3;
145148
ret = crypto_shash_init(&sdesc->shash);
146149
if (ret < 0)
147150
goto out;
@@ -196,6 +199,9 @@ int TSS_checkhmac1(unsigned char *buffer,
196199
va_list argp;
197200
int ret;
198201

202+
if (!chip)
203+
return -ENODEV;
204+
199205
bufsize = LOAD32(buffer, TPM_SIZE_OFFSET);
200206
tag = LOAD16(buffer, 0);
201207
ordinal = command;
@@ -363,6 +369,9 @@ int trusted_tpm_send(unsigned char *cmd, size_t buflen)
363369
{
364370
int rc;
365371

372+
if (!chip)
373+
return -ENODEV;
374+
366375
dump_tpm_buf(cmd);
367376
rc = tpm_send(chip, cmd, buflen);
368377
dump_tpm_buf(cmd);
@@ -429,6 +438,9 @@ int oiap(struct tpm_buf *tb, uint32_t *handle, unsigned char *nonce)
429438
{
430439
int ret;
431440

441+
if (!chip)
442+
return -ENODEV;
443+
432444
INIT_BUF(tb);
433445
store16(tb, TPM_TAG_RQU_COMMAND);
434446
store32(tb, TPM_OIAP_SIZE);
@@ -1245,9 +1257,13 @@ static int __init init_trusted(void)
12451257
{
12461258
int ret;
12471259

1260+
/* encrypted_keys.ko depends on successful load of this module even if
1261+
* TPM is not used.
1262+
*/
12481263
chip = tpm_default_chip();
12491264
if (!chip)
1250-
return -ENOENT;
1265+
return 0;
1266+
12511267
ret = init_digests();
12521268
if (ret < 0)
12531269
goto err_put;
@@ -1269,10 +1285,12 @@ static int __init init_trusted(void)
12691285

12701286
static void __exit cleanup_trusted(void)
12711287
{
1272-
put_device(&chip->dev);
1273-
kfree(digests);
1274-
trusted_shash_release();
1275-
unregister_key_type(&key_type_trusted);
1288+
if (chip) {
1289+
put_device(&chip->dev);
1290+
kfree(digests);
1291+
trusted_shash_release();
1292+
unregister_key_type(&key_type_trusted);
1293+
}
12761294
}
12771295

12781296
late_initcall(init_trusted);

tools/testing/selftests/tpm2/tpm2.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
TPM2_CC_FLUSH_CONTEXT = 0x0165
2323
TPM2_CC_START_AUTH_SESSION = 0x0176
2424
TPM2_CC_GET_CAPABILITY = 0x017A
25+
TPM2_CC_GET_RANDOM = 0x017B
2526
TPM2_CC_PCR_READ = 0x017E
2627
TPM2_CC_POLICY_PCR = 0x017F
2728
TPM2_CC_PCR_EXTEND = 0x0182
@@ -357,9 +358,9 @@ def __init__(self, flags = 0):
357358
self.flags = flags
358359

359360
if (self.flags & Client.FLAG_SPACE) == 0:
360-
self.tpm = open('/dev/tpm0', 'r+b')
361+
self.tpm = open('/dev/tpm0', 'r+b', buffering=0)
361362
else:
362-
self.tpm = open('/dev/tpmrm0', 'r+b')
363+
self.tpm = open('/dev/tpmrm0', 'r+b', buffering=0)
363364

364365
def close(self):
365366
self.tpm.close()

tools/testing/selftests/tpm2/tpm2_tests.py

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,69 @@ def test_too_short_cmd(self):
158158
pass
159159
self.assertEqual(rejected, True)
160160

161+
def test_read_partial_resp(self):
162+
try:
163+
fmt = '>HIIH'
164+
cmd = struct.pack(fmt,
165+
tpm2.TPM2_ST_NO_SESSIONS,
166+
struct.calcsize(fmt),
167+
tpm2.TPM2_CC_GET_RANDOM,
168+
0x20)
169+
self.client.tpm.write(cmd)
170+
hdr = self.client.tpm.read(10)
171+
sz = struct.unpack('>I', hdr[2:6])[0]
172+
rsp = self.client.tpm.read()
173+
except:
174+
pass
175+
self.assertEqual(sz, 10 + 2 + 32)
176+
self.assertEqual(len(rsp), 2 + 32)
177+
178+
def test_read_partial_overwrite(self):
179+
try:
180+
fmt = '>HIIH'
181+
cmd = struct.pack(fmt,
182+
tpm2.TPM2_ST_NO_SESSIONS,
183+
struct.calcsize(fmt),
184+
tpm2.TPM2_CC_GET_RANDOM,
185+
0x20)
186+
self.client.tpm.write(cmd)
187+
# Read part of the respone
188+
rsp1 = self.client.tpm.read(15)
189+
190+
# Send a new cmd
191+
self.client.tpm.write(cmd)
192+
193+
# Read the whole respone
194+
rsp2 = self.client.tpm.read()
195+
except:
196+
pass
197+
self.assertEqual(len(rsp1), 15)
198+
self.assertEqual(len(rsp2), 10 + 2 + 32)
199+
200+
def test_send_two_cmds(self):
201+
rejected = False
202+
try:
203+
fmt = '>HIIH'
204+
cmd = struct.pack(fmt,
205+
tpm2.TPM2_ST_NO_SESSIONS,
206+
struct.calcsize(fmt),
207+
tpm2.TPM2_CC_GET_RANDOM,
208+
0x20)
209+
self.client.tpm.write(cmd)
210+
211+
# expect the second one to raise -EBUSY error
212+
self.client.tpm.write(cmd)
213+
rsp = self.client.tpm.read()
214+
215+
except IOError, e:
216+
# read the response
217+
rsp = self.client.tpm.read()
218+
rejected = True
219+
pass
220+
except:
221+
pass
222+
self.assertEqual(rejected, True)
223+
161224
class SpaceTest(unittest.TestCase):
162225
def setUp(self):
163226
logging.basicConfig(filename='SpaceTest.log', level=logging.DEBUG)

0 commit comments

Comments
 (0)