0

media: Prevent H264 PPS parsing in encrypted range

On AMD platforms with HW protected content, we can end up receiving a
bitstream that has a PPS in the clear followed by the PPS encrypted.
While this is not technically a compliant H264 stream, it is something
we end up parsing. The PPS parsing is the only thing in the parser which
checks if there are more bytes left as a condition of continuing
parsing. This now adds a check there to ensure those bytes are in an
unencrypted range.

(A prior fix for this limited the bit reader's range, but that broke the
calculation for the slice header size).

BUG=b:208888853
TEST= HW protected content plays correctly on Intel and AMD

Change-Id: Ic65a8b1468b3b3e53c61fc85c2cca9a2c4cf1cdb
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3402628
Reviewed-by: Xiaohan Wang <xhwang@chromium.org>
Commit-Queue: Jeffrey Kardatzke <jkardatzke@google.com>
Cr-Commit-Position: refs/heads/main@{#961154}
This commit is contained in:
Jeffrey Kardatzke
2022-01-19 22:10:42 +00:00
committed by Chromium LUCI CQ
parent 59da74b999
commit 4af4d999af

@ -1200,7 +1200,15 @@ H264Parser::Result H264Parser::ParsePPS(int* pps_id) {
READ_BOOL_OR_RETURN(&pps->constrained_intra_pred_flag);
READ_BOOL_OR_RETURN(&pps->redundant_pic_cnt_present_flag);
if (br_.HasMoreRBSPData()) {
bool pps_remainder_unencrypted = true;
if (encrypted_ranges_.size()) {
Ranges<const uint8_t*> pps_range;
pps_range.Add(previous_nalu_range_.end(0) - br_.NumBitsLeft() / 8,
previous_nalu_range_.end(0));
pps_remainder_unencrypted =
(encrypted_ranges_.IntersectionWith(pps_range).size() == 0);
}
if (pps_remainder_unencrypted && br_.HasMoreRBSPData()) {
READ_BOOL_OR_RETURN(&pps->transform_8x8_mode_flag);
READ_BOOL_OR_RETURN(&pps->pic_scaling_matrix_present_flag);