@@ -1169,7 +1169,11 @@ int avc_ca_pmt(struct firedtv *fdtv, char *msg, int length)
read_pos += program_info_length;
write_pos += program_info_length;
}
- while (read_pos < length) {
+ while (read_pos + 4 < length) {
+ if (write_pos + 4 >= sizeof(c->operand) - 4) {
+ ret = -EINVAL;
+ goto out;
+ }
c->operand[write_pos++] = msg[read_pos++];
c->operand[write_pos++] = msg[read_pos++];
c->operand[write_pos++] = msg[read_pos++];
@@ -1181,13 +1185,17 @@ int avc_ca_pmt(struct firedtv *fdtv, char *msg, int length)
c->operand[write_pos++] = es_info_length >> 8;
c->operand[write_pos++] = es_info_length & 0xff;
if (es_info_length > 0) {
+ if (read_pos >= length) {
+ ret = -EINVAL;
+ goto out;
+ }
pmt_cmd_id = msg[read_pos++];
if (pmt_cmd_id != 1 && pmt_cmd_id != 4)
dev_err(fdtv->device, "invalid pmt_cmd_id %d at stream level\n",
pmt_cmd_id);
- if (es_info_length > sizeof(c->operand) - 4 -
- write_pos) {
+ if (es_info_length > sizeof(c->operand) - 4 - write_pos ||
+ es_info_length > length - read_pos) {
ret = -EINVAL;
goto out;
}
@@ -135,6 +135,8 @@ static int fdtv_ca_pmt(struct firedtv *fdtv, void *arg)
data_length = 0;
for (i = 0; i < (msg->msg[3] & 0x7f); i++)
data_length = (data_length << 8) + msg->msg[data_pos++];
+ if (((msg->msg[3] & 0x7f) + date_length) > (sizeof(msg->msg) - 4))
+ return -EINVAL;
} else {
data_length = msg->msg[3];
}
For CVE-2021-3542: 1、read_pos will be added four times in the patch, so use "read_pos + 4 < length" and write_pos as well 2. The last four bits of c->operand are used for CRC, so "sizeof (C - > operand) - 4" is used 3. "read_pos+=2" is added after the end of read_pos, so add value (read_pos >= length) 4. In order to avoid memcpy crossing the boundary, es_ info_ length > length - read_ pos 5. When the date_length is a specific input of a construction,it will cause memcpy to exceed the boundary, "(MSG - > MSG [3] & 0x7F) + date_ length) > (sizeof(msg->msg) - 4)" Signed-off-by: yangyanchao <yangyanchao6@huawei.com> --- drivers/media/firewire/firedtv-avc.c | 14 +++++++++++--- drivers/media/firewire/firedtv-ci.c | 2 ++ 2 files changed, 13 insertions(+), 3 deletions(-)