@@ -423,8 +423,9 @@ ssize_t tpm_transmit(struct tpm_chip *chip, const u8 *buf, size_t bufsiz,
423
423
* The function extracts tpm out header return code
424
424
*
425
425
* @chip: TPM chip to use
426
- * @cmd: TPM command buffer
427
- * @len: length of the TPM command
426
+ * @buf: TPM command buffer
427
+ * @bufsiz: length of the buffer
428
+ * @min_rsp_body_length: minimum expected length of response body
428
429
* @flags: tpm transmit flags - bitmap
429
430
* @desc: command description used in the error message
430
431
*
@@ -433,26 +434,35 @@ ssize_t tpm_transmit(struct tpm_chip *chip, const u8 *buf, size_t bufsiz,
433
434
* A negative number for system errors (errno).
434
435
* A positive number for a TPM error.
435
436
*/
436
- ssize_t tpm_transmit_cmd (struct tpm_chip * chip , const void * cmd ,
437
- int len , unsigned int flags , const char * desc )
437
+ ssize_t tpm_transmit_cmd (struct tpm_chip * chip , const void * buf ,
438
+ size_t bufsiz , size_t min_rsp_body_length ,
439
+ unsigned int flags , const char * desc )
438
440
{
439
441
const struct tpm_output_header * header ;
440
442
int err ;
443
+ ssize_t len ;
441
444
442
- len = tpm_transmit (chip , (const u8 * )cmd , len , flags );
445
+ len = tpm_transmit (chip , (const u8 * )buf , bufsiz , flags );
443
446
if (len < 0 )
444
447
return len ;
445
448
else if (len < TPM_HEADER_SIZE )
446
449
return - EFAULT ;
447
450
448
- header = cmd ;
451
+ header = buf ;
452
+ if (len != be32_to_cpu (header -> length ))
453
+ return - EFAULT ;
449
454
450
455
err = be32_to_cpu (header -> return_code );
451
456
if (err != 0 && desc )
452
457
dev_err (& chip -> dev , "A TPM error (%d) occurred %s\n" , err ,
453
458
desc );
459
+ if (err )
460
+ return err ;
461
+
462
+ if (len < min_rsp_body_length + TPM_HEADER_SIZE )
463
+ return - EFAULT ;
454
464
455
- return err ;
465
+ return 0 ;
456
466
}
457
467
458
468
#define TPM_DIGEST_SIZE 20
@@ -468,7 +478,7 @@ static const struct tpm_input_header tpm_getcap_header = {
468
478
};
469
479
470
480
ssize_t tpm_getcap (struct tpm_chip * chip , u32 subcap_id , cap_t * cap ,
471
- const char * desc )
481
+ const char * desc , size_t min_cap_length )
472
482
{
473
483
struct tpm_cmd_t tpm_cmd ;
474
484
int rc ;
@@ -491,8 +501,8 @@ ssize_t tpm_getcap(struct tpm_chip *chip, u32 subcap_id, cap_t *cap,
491
501
tpm_cmd .params .getcap_in .subcap_size = cpu_to_be32 (4 );
492
502
tpm_cmd .params .getcap_in .subcap = cpu_to_be32 (subcap_id );
493
503
}
494
- rc = tpm_transmit_cmd (chip , & tpm_cmd , TPM_INTERNAL_RESULT_SIZE , 0 ,
495
- desc );
504
+ rc = tpm_transmit_cmd (chip , & tpm_cmd , TPM_INTERNAL_RESULT_SIZE ,
505
+ min_cap_length , 0 , desc );
496
506
if (!rc )
497
507
* cap = tpm_cmd .params .getcap_out .cap ;
498
508
return rc ;
@@ -516,7 +526,7 @@ static int tpm_startup(struct tpm_chip *chip, __be16 startup_type)
516
526
517
527
start_cmd .params .startup_in .startup_type = startup_type ;
518
528
return tpm_transmit_cmd (chip , & start_cmd , TPM_INTERNAL_RESULT_SIZE , 0 ,
519
- "attempting to start the TPM" );
529
+ 0 , "attempting to start the TPM" );
520
530
}
521
531
522
532
int tpm_get_timeouts (struct tpm_chip * chip )
@@ -545,7 +555,8 @@ int tpm_get_timeouts(struct tpm_chip *chip)
545
555
return 0 ;
546
556
}
547
557
548
- rc = tpm_getcap (chip , TPM_CAP_PROP_TIS_TIMEOUT , & cap , NULL );
558
+ rc = tpm_getcap (chip , TPM_CAP_PROP_TIS_TIMEOUT , & cap , NULL ,
559
+ sizeof (cap .timeout ));
549
560
if (rc == TPM_ERR_INVALID_POSTINIT ) {
550
561
/* The TPM is not started, we are the first to talk to it.
551
562
Execute a startup command. */
@@ -554,8 +565,10 @@ int tpm_get_timeouts(struct tpm_chip *chip)
554
565
return rc ;
555
566
556
567
rc = tpm_getcap (chip , TPM_CAP_PROP_TIS_TIMEOUT , & cap ,
557
- "attempting to determine the timeouts" );
568
+ "attempting to determine the timeouts" ,
569
+ sizeof (cap .timeout ));
558
570
}
571
+
559
572
if (rc ) {
560
573
dev_err (& chip -> dev ,
561
574
"A TPM error (%zd) occurred attempting to determine the timeouts\n" ,
@@ -617,7 +630,8 @@ int tpm_get_timeouts(struct tpm_chip *chip)
617
630
chip -> timeout_d = usecs_to_jiffies (timeout_eff [3 ]);
618
631
619
632
rc = tpm_getcap (chip , TPM_CAP_PROP_TIS_DURATION , & cap ,
620
- "attempting to determine the durations" );
633
+ "attempting to determine the durations" ,
634
+ sizeof (cap .duration ));
621
635
if (rc )
622
636
return rc ;
623
637
@@ -668,13 +682,14 @@ static int tpm_continue_selftest(struct tpm_chip *chip)
668
682
struct tpm_cmd_t cmd ;
669
683
670
684
cmd .header .in = continue_selftest_header ;
671
- rc = tpm_transmit_cmd (chip , & cmd , CONTINUE_SELFTEST_RESULT_SIZE , 0 ,
685
+ rc = tpm_transmit_cmd (chip , & cmd , CONTINUE_SELFTEST_RESULT_SIZE , 0 , 0 ,
672
686
"continue selftest" );
673
687
return rc ;
674
688
}
675
689
676
690
#define TPM_ORDINAL_PCRREAD cpu_to_be32(21)
677
691
#define READ_PCR_RESULT_SIZE 30
692
+ #define READ_PCR_RESULT_BODY_SIZE 20
678
693
static const struct tpm_input_header pcrread_header = {
679
694
.tag = TPM_TAG_RQU_COMMAND ,
680
695
.length = cpu_to_be32 (14 ),
@@ -688,7 +703,8 @@ int tpm_pcr_read_dev(struct tpm_chip *chip, int pcr_idx, u8 *res_buf)
688
703
689
704
cmd .header .in = pcrread_header ;
690
705
cmd .params .pcrread_in .pcr_idx = cpu_to_be32 (pcr_idx );
691
- rc = tpm_transmit_cmd (chip , & cmd , READ_PCR_RESULT_SIZE , 0 ,
706
+ rc = tpm_transmit_cmd (chip , & cmd , READ_PCR_RESULT_SIZE ,
707
+ READ_PCR_RESULT_BODY_SIZE , 0 ,
692
708
"attempting to read a pcr value" );
693
709
694
710
if (rc == 0 )
@@ -751,6 +767,7 @@ EXPORT_SYMBOL_GPL(tpm_pcr_read);
751
767
752
768
#define TPM_ORD_PCR_EXTEND cpu_to_be32(20)
753
769
#define EXTEND_PCR_RESULT_SIZE 34
770
+ #define EXTEND_PCR_RESULT_BODY_SIZE 24
754
771
static const struct tpm_input_header pcrextend_header = {
755
772
.tag = TPM_TAG_RQU_COMMAND ,
756
773
.length = cpu_to_be32 (34 ),
@@ -786,7 +803,8 @@ int tpm_pcr_extend(u32 chip_num, int pcr_idx, const u8 *hash)
786
803
cmd .header .in = pcrextend_header ;
787
804
cmd .params .pcrextend_in .pcr_idx = cpu_to_be32 (pcr_idx );
788
805
memcpy (cmd .params .pcrextend_in .hash , hash , TPM_DIGEST_SIZE );
789
- rc = tpm_transmit_cmd (chip , & cmd , EXTEND_PCR_RESULT_SIZE , 0 ,
806
+ rc = tpm_transmit_cmd (chip , & cmd , EXTEND_PCR_RESULT_SIZE ,
807
+ EXTEND_PCR_RESULT_BODY_SIZE , 0 ,
790
808
"attempting extend a PCR value" );
791
809
792
810
tpm_put_ops (chip );
@@ -890,7 +908,7 @@ int tpm_send(u32 chip_num, void *cmd, size_t buflen)
890
908
if (chip == NULL )
891
909
return - ENODEV ;
892
910
893
- rc = tpm_transmit_cmd (chip , cmd , buflen , 0 , "attempting tpm_cmd" );
911
+ rc = tpm_transmit_cmd (chip , cmd , buflen , 0 , 0 , "attempting tpm_cmd" );
894
912
895
913
tpm_put_ops (chip );
896
914
return rc ;
@@ -992,15 +1010,16 @@ int tpm_pm_suspend(struct device *dev)
992
1010
cmd .params .pcrextend_in .pcr_idx = cpu_to_be32 (tpm_suspend_pcr );
993
1011
memcpy (cmd .params .pcrextend_in .hash , dummy_hash ,
994
1012
TPM_DIGEST_SIZE );
995
- rc = tpm_transmit_cmd (chip , & cmd , EXTEND_PCR_RESULT_SIZE , 0 ,
1013
+ rc = tpm_transmit_cmd (chip , & cmd , EXTEND_PCR_RESULT_SIZE ,
1014
+ EXTEND_PCR_RESULT_BODY_SIZE , 0 ,
996
1015
"extending dummy pcr before suspend" );
997
1016
}
998
1017
999
1018
/* now do the actual savestate */
1000
1019
for (try = 0 ; try < TPM_RETRY ; try ++ ) {
1001
1020
cmd .header .in = savestate_header ;
1002
1021
rc = tpm_transmit_cmd (chip , & cmd , SAVESTATE_RESULT_SIZE , 0 ,
1003
- NULL );
1022
+ 0 , NULL );
1004
1023
1005
1024
/*
1006
1025
* If the TPM indicates that it is too busy to respond to
@@ -1062,7 +1081,7 @@ int tpm_get_random(u32 chip_num, u8 *out, size_t max)
1062
1081
{
1063
1082
struct tpm_chip * chip ;
1064
1083
struct tpm_cmd_t tpm_cmd ;
1065
- u32 recd , num_bytes = min_t (u32 , max , TPM_MAX_RNG_DATA );
1084
+ u32 recd , num_bytes = min_t (u32 , max , TPM_MAX_RNG_DATA ), rlength ;
1066
1085
int err , total = 0 , retries = 5 ;
1067
1086
u8 * dest = out ;
1068
1087
@@ -1085,11 +1104,20 @@ int tpm_get_random(u32 chip_num, u8 *out, size_t max)
1085
1104
1086
1105
err = tpm_transmit_cmd (chip , & tpm_cmd ,
1087
1106
TPM_GETRANDOM_RESULT_SIZE + num_bytes ,
1107
+ offsetof(struct tpm_getrandom_out ,
1108
+ rng_data ),
1088
1109
0 , "attempting get random" );
1089
1110
if (err )
1090
1111
break ;
1091
1112
1092
1113
recd = be32_to_cpu (tpm_cmd .params .getrandom_out .rng_data_len );
1114
+
1115
+ rlength = be32_to_cpu (tpm_cmd .header .out .length );
1116
+ if (rlength < offsetof(struct tpm_getrandom_out , rng_data ) +
1117
+ recd ) {
1118
+ total = - EFAULT ;
1119
+ break ;
1120
+ }
1093
1121
memcpy (dest , tpm_cmd .params .getrandom_out .rng_data , recd );
1094
1122
1095
1123
dest += recd ;
0 commit comments