Skip to content

Commit 3435f1c

Browse files
lrgirdwolgirdwood
authored andcommitted
rimage: reject reversed manifest size fields
The signed module size was computed as a difference of two header fields from the image without an ordering check, underflowing to a huge value that was then hashed past the buffer. Reject a header whose size is less than its header length. Signed-off-by: Liam Girdwood <liam.r.girdwood@linux.intel.com>
1 parent 36aa1dc commit 3435f1c

1 file changed

Lines changed: 38 additions & 0 deletions

File tree

tools/rimage/src/pkcs1_5.c

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -929,9 +929,28 @@ int ri_manifest_verify_v1_8(struct image *image)
929929
MAN_RSA_SIGNATURE_LEN);
930930

931931
char *const data2 = (char *)man + MAN_SIG_PKG_OFFSET_V1_8;
932+
933+
/* css.size and css.header_len come from the (untrusted) image; reject
934+
* a reversed ordering that would underflow the unsigned size2 below.
935+
*/
936+
if (man->css.size < man->css.header_len) {
937+
fprintf(stderr, "error: invalid css size %u < header_len %u\n",
938+
man->css.size, man->css.header_len);
939+
return -EINVAL;
940+
}
941+
932942
unsigned const size2 =
933943
(man->css.size - man->css.header_len) * sizeof(uint32_t);
934944

945+
/* size2 is derived from untrusted css fields and is hashed starting at
946+
* data2; make sure that range stays within the verified image buffer.
947+
*/
948+
if (image->image_end < MAN_SIG_PKG_OFFSET_V1_8 ||
949+
size2 > image->image_end - MAN_SIG_PKG_OFFSET_V1_8) {
950+
fprintf(stderr, "error: signed payload size 0x%x exceeds image\n", size2);
951+
return -EINVAL;
952+
}
953+
935954
return pkcs_v1_5_verify_man_v1_8(image, man, data1, size1, data2, size2);
936955
}
937956

@@ -946,9 +965,28 @@ int ri_manifest_verify_v2_5(struct image *image)
946965
MAN_RSA_SIGNATURE_LEN_2_5);
947966

948967
char *const data2 = (char *)man + MAN_SIG_PKG_OFFSET_V2_5;
968+
969+
/* css.size and css.header_len come from the (untrusted) image; reject
970+
* a reversed ordering that would underflow the unsigned size2 below.
971+
*/
972+
if (man->css.size < man->css.header_len) {
973+
fprintf(stderr, "error: invalid css size %u < header_len %u\n",
974+
man->css.size, man->css.header_len);
975+
return -EINVAL;
976+
}
977+
949978
unsigned const size2 =
950979
(man->css.size - man->css.header_len) * sizeof(uint32_t);
951980

981+
/* size2 is derived from untrusted css fields and is hashed starting at
982+
* data2; make sure that range stays within the verified image buffer.
983+
*/
984+
if (image->image_end < MAN_SIG_PKG_OFFSET_V2_5 ||
985+
size2 > image->image_end - MAN_SIG_PKG_OFFSET_V2_5) {
986+
fprintf(stderr, "error: signed payload size 0x%x exceeds image\n", size2);
987+
return -EINVAL;
988+
}
989+
952990
return pkcs_v1_5_verify_man_v2_5(image, man, data1, size1, data2, size2);
953991
}
954992

0 commit comments

Comments
 (0)