Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge tag 'media/v6.12-2' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media

Pull media fixes from Mauro Carvalho Chehab:

- dvb-core fixes for vb2 check and device registration

- v4l2-core: fix an issue with error handling for VIDIOC_G_CTRL

- vb2 core: fix an issue with vb plane copy logic

- videobuf2-core: copy vb planes unconditionally

- vivid: fix buffer overwrite when using > 32 buffers

- vivid: fix a potential division by zero due to an issue at v4l2-tpg

- some spectre vulnerability fixes

- several OOM access fixes

- some buffer overflow fixes

* tag 'media/v6.12-2' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media:
media: videobuf2-core: copy vb planes unconditionally
media: dvbdev: fix the logic when DVB_DYNAMIC_MINORS is not set
media: vivid: fix buffer overwrite when using > 32 buffers
media: pulse8-cec: fix data timestamp at pulse8_setup()
media: cec: extron-da-hd-4k-plus: don't use -1 as an error code
media: stb0899_algo: initialize cfr before using it
media: adv7604: prevent underflow condition when reporting colorspace
media: cx24116: prevent overflows on SNR calculus
media: ar0521: don't overflow when checking PLL values
media: s5p-jpeg: prevent buffer overflows
media: av7110: fix a spectre vulnerability
media: mgb4: protect driver against spectre
media: dvb_frontend: don't play tricks with underflow values
media: dvbdev: prevent the risk of out of memory access
media: v4l2-tpg: prevent the risk of a division by zero
media: v4l2-ctrls-api: fix error handling for v4l2_g_ctrl()
media: dvb-core: add missing buffer index check

+118 -63
+3 -3
drivers/media/cec/usb/extron-da-hd-4k-plus/extron-da-hd-4k-plus.c
··· 348 348 349 349 /* Return if not a CTA-861 extension block */ 350 350 if (size < 256 || edid[0] != 0x02 || edid[1] != 0x03) 351 - return -1; 351 + return -ENOENT; 352 352 353 353 /* search tag */ 354 354 d = edid[0x02] & 0x7f; 355 355 if (d <= 4) 356 - return -1; 356 + return -ENOENT; 357 357 358 358 i = 0x04; 359 359 end = 0x00 + d; ··· 371 371 return offset + i; 372 372 i += len + 1; 373 373 } while (i < end); 374 - return -1; 374 + return -ENOENT; 375 375 } 376 376 377 377 static void extron_edid_crc(u8 *edid)
+1 -1
drivers/media/cec/usb/pulse8/pulse8-cec.c
··· 685 685 err = pulse8_send_and_wait(pulse8, cmd, 1, cmd[0], 4); 686 686 if (err) 687 687 return err; 688 - date = (data[0] << 24) | (data[1] << 16) | (data[2] << 8) | data[3]; 688 + date = ((unsigned)data[0] << 24) | (data[1] << 16) | (data[2] << 8) | data[3]; 689 689 dev_info(pulse8->dev, "Firmware build date %ptT\n", &date); 690 690 691 691 dev_dbg(pulse8->dev, "Persistent config:\n");
+3
drivers/media/common/v4l2-tpg/v4l2-tpg-core.c
··· 1795 1795 unsigned p; 1796 1796 unsigned x; 1797 1797 1798 + if (WARN_ON_ONCE(!tpg->src_width || !tpg->scaled_width)) 1799 + return; 1800 + 1798 1801 switch (tpg->pattern) { 1799 1802 case TPG_PAT_GREEN: 1800 1803 contrast = TPG_COLOR_100_RED;
+15 -13
drivers/media/common/videobuf2/videobuf2-core.c
··· 1482 1482 } 1483 1483 vb->planes[plane].dbuf_mapped = 1; 1484 1484 } 1485 + } else { 1486 + for (plane = 0; plane < vb->num_planes; ++plane) 1487 + dma_buf_put(planes[plane].dbuf); 1488 + } 1485 1489 1486 - /* 1487 - * Now that everything is in order, copy relevant information 1488 - * provided by userspace. 1489 - */ 1490 - for (plane = 0; plane < vb->num_planes; ++plane) { 1491 - vb->planes[plane].bytesused = planes[plane].bytesused; 1492 - vb->planes[plane].length = planes[plane].length; 1493 - vb->planes[plane].m.fd = planes[plane].m.fd; 1494 - vb->planes[plane].data_offset = planes[plane].data_offset; 1495 - } 1490 + /* 1491 + * Now that everything is in order, copy relevant information 1492 + * provided by userspace. 1493 + */ 1494 + for (plane = 0; plane < vb->num_planes; ++plane) { 1495 + vb->planes[plane].bytesused = planes[plane].bytesused; 1496 + vb->planes[plane].length = planes[plane].length; 1497 + vb->planes[plane].m.fd = planes[plane].m.fd; 1498 + vb->planes[plane].data_offset = planes[plane].data_offset; 1499 + } 1496 1500 1501 + if (reacquired) { 1497 1502 /* 1498 1503 * Call driver-specific initialization on the newly acquired buffer, 1499 1504 * if provided. ··· 1508 1503 dprintk(q, 1, "buffer initialization failed\n"); 1509 1504 goto err_put_vb2_buf; 1510 1505 } 1511 - } else { 1512 - for (plane = 0; plane < vb->num_planes; ++plane) 1513 - dma_buf_put(planes[plane].dbuf); 1514 1506 } 1515 1507 1516 1508 ret = call_vb_qop(vb, buf_prepare, vb);
+2 -2
drivers/media/dvb-core/dvb_frontend.c
··· 443 443 444 444 default: 445 445 fepriv->auto_step++; 446 - fepriv->auto_sub_step = -1; /* it'll be incremented to 0 in a moment */ 447 - break; 446 + fepriv->auto_sub_step = 0; 447 + continue; 448 448 } 449 449 450 450 if (!ready) fepriv->auto_sub_step++;
+7 -1
drivers/media/dvb-core/dvb_vb2.c
··· 366 366 int dvb_vb2_expbuf(struct dvb_vb2_ctx *ctx, struct dmx_exportbuffer *exp) 367 367 { 368 368 struct vb2_queue *q = &ctx->vb_q; 369 + struct vb2_buffer *vb2 = vb2_get_buffer(q, exp->index); 369 370 int ret; 370 371 371 - ret = vb2_core_expbuf(&ctx->vb_q, &exp->fd, q->type, q->bufs[exp->index], 372 + if (!vb2) { 373 + dprintk(1, "[%s] invalid buffer index\n", ctx->name); 374 + return -EINVAL; 375 + } 376 + 377 + ret = vb2_core_expbuf(&ctx->vb_q, &exp->fd, q->type, vb2, 372 378 0, exp->flags); 373 379 if (ret) { 374 380 dprintk(1, "[%s] index=%d errno=%d\n", ctx->name,
+11 -5
drivers/media/dvb-core/dvbdev.c
··· 86 86 static int dvb_device_open(struct inode *inode, struct file *file) 87 87 { 88 88 struct dvb_device *dvbdev; 89 + unsigned int minor = iminor(inode); 90 + 91 + if (minor >= MAX_DVB_MINORS) 92 + return -ENODEV; 89 93 90 94 mutex_lock(&dvbdev_mutex); 91 95 down_read(&minor_rwsem); 92 - dvbdev = dvb_minors[iminor(inode)]; 96 + 97 + dvbdev = dvb_minors[minor]; 93 98 94 99 if (dvbdev && dvbdev->fops) { 95 100 int err = 0; ··· 530 525 for (minor = 0; minor < MAX_DVB_MINORS; minor++) 531 526 if (!dvb_minors[minor]) 532 527 break; 533 - if (minor == MAX_DVB_MINORS) { 528 + #else 529 + minor = nums2minor(adap->num, type, id); 530 + #endif 531 + if (minor >= MAX_DVB_MINORS) { 534 532 if (new_node) { 535 533 list_del(&new_node->list_head); 536 534 kfree(dvbdevfops); ··· 546 538 mutex_unlock(&dvbdev_register_lock); 547 539 return -EINVAL; 548 540 } 549 - #else 550 - minor = nums2minor(adap->num, type, id); 551 - #endif 541 + 552 542 dvbdev->minor = minor; 553 543 dvb_minors[minor] = dvb_device_get(dvbdev); 554 544 up_write(&minor_rwsem);
+6 -1
drivers/media/dvb-frontends/cx24116.c
··· 741 741 { 742 742 struct cx24116_state *state = fe->demodulator_priv; 743 743 u8 snr_reading; 744 + int ret; 744 745 static const u32 snr_tab[] = { /* 10 x Table (rounded up) */ 745 746 0x00000, 0x0199A, 0x03333, 0x04ccD, 0x06667, 746 747 0x08000, 0x0999A, 0x0b333, 0x0cccD, 0x0e667, ··· 750 749 751 750 dprintk("%s()\n", __func__); 752 751 753 - snr_reading = cx24116_readreg(state, CX24116_REG_QUALITY0); 752 + ret = cx24116_readreg(state, CX24116_REG_QUALITY0); 753 + if (ret < 0) 754 + return ret; 755 + 756 + snr_reading = ret; 754 757 755 758 if (snr_reading >= 0xa0 /* 100% */) 756 759 *snr = 0xffff;
+1 -1
drivers/media/dvb-frontends/stb0899_algo.c
··· 269 269 270 270 short int derot_freq = 0, last_derot_freq = 0, derot_limit, next_loop = 3; 271 271 int index = 0; 272 - u8 cfr[2]; 272 + u8 cfr[2] = {0}; 273 273 u8 reg; 274 274 275 275 internal->status = NOCARRIER;
+17 -9
drivers/media/i2c/adv7604.c
··· 2519 2519 const struct adv76xx_chip_info *info = state->info; 2520 2520 struct v4l2_dv_timings timings; 2521 2521 struct stdi_readback stdi; 2522 - u8 reg_io_0x02 = io_read(sd, 0x02); 2522 + int ret; 2523 + u8 reg_io_0x02; 2523 2524 u8 edid_enabled; 2524 2525 u8 cable_det; 2525 - 2526 2526 static const char * const csc_coeff_sel_rb[16] = { 2527 2527 "bypassed", "YPbPr601 -> RGB", "reserved", "YPbPr709 -> RGB", 2528 2528 "reserved", "RGB -> YPbPr601", "reserved", "RGB -> YPbPr709", ··· 2621 2621 v4l2_info(sd, "-----Color space-----\n"); 2622 2622 v4l2_info(sd, "RGB quantization range ctrl: %s\n", 2623 2623 rgb_quantization_range_txt[state->rgb_quantization_range]); 2624 - v4l2_info(sd, "Input color space: %s\n", 2625 - input_color_space_txt[reg_io_0x02 >> 4]); 2626 - v4l2_info(sd, "Output color space: %s %s, alt-gamma %s\n", 2627 - (reg_io_0x02 & 0x02) ? "RGB" : "YCbCr", 2628 - (((reg_io_0x02 >> 2) & 0x01) ^ (reg_io_0x02 & 0x01)) ? 2629 - "(16-235)" : "(0-255)", 2630 - (reg_io_0x02 & 0x08) ? "enabled" : "disabled"); 2624 + 2625 + ret = io_read(sd, 0x02); 2626 + if (ret < 0) { 2627 + v4l2_info(sd, "Can't read Input/Output color space\n"); 2628 + } else { 2629 + reg_io_0x02 = ret; 2630 + 2631 + v4l2_info(sd, "Input color space: %s\n", 2632 + input_color_space_txt[reg_io_0x02 >> 4]); 2633 + v4l2_info(sd, "Output color space: %s %s, alt-gamma %s\n", 2634 + (reg_io_0x02 & 0x02) ? "RGB" : "YCbCr", 2635 + (((reg_io_0x02 >> 2) & 0x01) ^ (reg_io_0x02 & 0x01)) ? 2636 + "(16-235)" : "(0-255)", 2637 + (reg_io_0x02 & 0x08) ? "enabled" : "disabled"); 2638 + } 2631 2639 v4l2_info(sd, "Color space conversion: %s\n", 2632 2640 csc_coeff_sel_rb[cp_read(sd, info->cp_csc) >> 4]); 2633 2641
+2 -2
drivers/media/i2c/ar0521.c
··· 255 255 continue; /* Minimum value */ 256 256 if (new_mult > 254) 257 257 break; /* Maximum, larger pre won't work either */ 258 - if (sensor->extclk_freq * (u64)new_mult < AR0521_PLL_MIN * 258 + if (sensor->extclk_freq * (u64)new_mult < (u64)AR0521_PLL_MIN * 259 259 new_pre) 260 260 continue; 261 - if (sensor->extclk_freq * (u64)new_mult > AR0521_PLL_MAX * 261 + if (sensor->extclk_freq * (u64)new_mult > (u64)AR0521_PLL_MAX * 262 262 new_pre) 263 263 break; /* Larger pre won't work either */ 264 264 new_pll = div64_round_up(sensor->extclk_freq * (u64)new_mult,
+2
drivers/media/pci/mgb4/mgb4_cmt.c
··· 227 227 u32 config; 228 228 size_t i; 229 229 230 + freq_range = array_index_nospec(freq_range, ARRAY_SIZE(cmt_vals_in)); 231 + 230 232 addr = cmt_addrs_in[vindev->config->id]; 231 233 reg_set = cmt_vals_in[freq_range]; 232 234
+11 -6
drivers/media/platform/samsung/s5p-jpeg/jpeg-core.c
··· 775 775 (unsigned long)vb2_plane_vaddr(&vb->vb2_buf, 0) + ctx->out_q.sos + 2; 776 776 jpeg_buffer.curr = 0; 777 777 778 - word = 0; 779 - 780 778 if (get_word_be(&jpeg_buffer, &word)) 781 779 return; 782 - jpeg_buffer.size = (long)word - 2; 780 + 781 + if (word < 2) 782 + jpeg_buffer.size = 0; 783 + else 784 + jpeg_buffer.size = (long)word - 2; 785 + 783 786 jpeg_buffer.data += 2; 784 787 jpeg_buffer.curr = 0; 785 788 ··· 1061 1058 if (byte == -1) 1062 1059 return -1; 1063 1060 *word = (unsigned int)byte | temp; 1061 + 1064 1062 return 0; 1065 1063 } 1066 1064 ··· 1149 1145 if (get_word_be(&jpeg_buffer, &word)) 1150 1146 break; 1151 1147 length = (long)word - 2; 1152 - if (!length) 1148 + if (length <= 0) 1153 1149 return false; 1154 1150 sof = jpeg_buffer.curr; /* after 0xffc0 */ 1155 1151 sof_len = length; ··· 1180 1176 if (get_word_be(&jpeg_buffer, &word)) 1181 1177 break; 1182 1178 length = (long)word - 2; 1183 - if (!length) 1179 + if (length <= 0) 1184 1180 return false; 1185 1181 if (n_dqt >= S5P_JPEG_MAX_MARKER) 1186 1182 return false; ··· 1193 1189 if (get_word_be(&jpeg_buffer, &word)) 1194 1190 break; 1195 1191 length = (long)word - 2; 1196 - if (!length) 1192 + if (length <= 0) 1197 1193 return false; 1198 1194 if (n_dht >= S5P_JPEG_MAX_MARKER) 1199 1195 return false; ··· 1218 1214 if (get_word_be(&jpeg_buffer, &word)) 1219 1215 break; 1220 1216 length = (long)word - 2; 1217 + /* No need to check underflows as skip() does it */ 1221 1218 skip(&jpeg_buffer, length); 1222 1219 break; 1223 1220 }
+1 -1
drivers/media/test-drivers/vivid/vivid-core.c
··· 910 910 * videobuf2-core.c to MAX_BUFFER_INDEX. 911 911 */ 912 912 if (buf_type == V4L2_BUF_TYPE_VIDEO_CAPTURE) 913 - q->max_num_buffers = 64; 913 + q->max_num_buffers = MAX_VID_CAP_BUFFERS; 914 914 if (buf_type == V4L2_BUF_TYPE_SDR_CAPTURE) 915 915 q->max_num_buffers = 1024; 916 916 if (buf_type == V4L2_BUF_TYPE_VBI_CAPTURE)
+3 -1
drivers/media/test-drivers/vivid/vivid-core.h
··· 26 26 #define MAX_INPUTS 16 27 27 /* The maximum number of outputs */ 28 28 #define MAX_OUTPUTS 16 29 + /* The maximum number of video capture buffers */ 30 + #define MAX_VID_CAP_BUFFERS 64 29 31 /* The maximum up or down scaling factor is 4 */ 30 32 #define MAX_ZOOM 4 31 33 /* The maximum image width/height are set to 4K DMT */ ··· 483 481 /* video capture */ 484 482 struct tpg_data tpg; 485 483 unsigned ms_vid_cap; 486 - bool must_blank[VIDEO_MAX_FRAME]; 484 + bool must_blank[MAX_VID_CAP_BUFFERS]; 487 485 488 486 const struct vivid_fmt *fmt_cap; 489 487 struct v4l2_fract timeperframe_vid_cap;
+1 -1
drivers/media/test-drivers/vivid/vivid-ctrls.c
··· 553 553 break; 554 554 case VIVID_CID_PERCENTAGE_FILL: 555 555 tpg_s_perc_fill(&dev->tpg, ctrl->val); 556 - for (i = 0; i < VIDEO_MAX_FRAME; i++) 556 + for (i = 0; i < MAX_VID_CAP_BUFFERS; i++) 557 557 dev->must_blank[i] = ctrl->val < 100; 558 558 break; 559 559 case VIVID_CID_INSERT_SAV:
+1 -1
drivers/media/test-drivers/vivid/vivid-vid-cap.c
··· 213 213 214 214 dev->vid_cap_seq_count = 0; 215 215 dprintk(dev, 1, "%s\n", __func__); 216 - for (i = 0; i < VIDEO_MAX_FRAME; i++) 216 + for (i = 0; i < MAX_VID_CAP_BUFFERS; i++) 217 217 dev->must_blank[i] = tpg_g_perc_fill(&dev->tpg) < 100; 218 218 if (dev->start_streaming_error) { 219 219 dev->start_streaming_error = false;
+11 -6
drivers/media/v4l2-core/v4l2-ctrls-api.c
··· 753 753 for (i = 0; i < master->ncontrols; i++) 754 754 cur_to_new(master->cluster[i]); 755 755 ret = call_op(master, g_volatile_ctrl); 756 - new_to_user(c, ctrl); 756 + if (!ret) 757 + ret = new_to_user(c, ctrl); 757 758 } else { 758 - cur_to_user(c, ctrl); 759 + ret = cur_to_user(c, ctrl); 759 760 } 760 761 v4l2_ctrl_unlock(master); 761 762 return ret; ··· 771 770 if (!ctrl || !ctrl->is_int) 772 771 return -EINVAL; 773 772 ret = get_ctrl(ctrl, &c); 774 - control->value = c.value; 773 + 774 + if (!ret) 775 + control->value = c.value; 776 + 775 777 return ret; 776 778 } 777 779 EXPORT_SYMBOL(v4l2_g_ctrl); ··· 815 811 int ret; 816 812 817 813 v4l2_ctrl_lock(ctrl); 818 - user_to_new(c, ctrl); 819 - ret = set_ctrl(fh, ctrl, 0); 814 + ret = user_to_new(c, ctrl); 820 815 if (!ret) 821 - cur_to_user(c, ctrl); 816 + ret = set_ctrl(fh, ctrl, 0); 817 + if (!ret) 818 + ret = cur_to_user(c, ctrl); 822 819 v4l2_ctrl_unlock(ctrl); 823 820 return ret; 824 821 }
+3 -1
drivers/staging/media/av7110/av7110.h
··· 88 88 u32 ir_config; 89 89 }; 90 90 91 + #define MAX_CI_SLOTS 2 92 + 91 93 /* place to store all the necessary device information */ 92 94 struct av7110 { 93 95 /* devices */ ··· 165 163 166 164 /* CA */ 167 165 168 - struct ca_slot_info ci_slot[2]; 166 + struct ca_slot_info ci_slot[MAX_CI_SLOTS]; 169 167 170 168 enum av7110_video_mode vidmode; 171 169 struct dmxdev dmxdev;
+17 -8
drivers/staging/media/av7110/av7110_ca.c
··· 26 26 27 27 void CI_handle(struct av7110 *av7110, u8 *data, u16 len) 28 28 { 29 + unsigned slot_num; 30 + 29 31 dprintk(8, "av7110:%p\n", av7110); 30 32 31 33 if (len < 3) 32 34 return; 33 35 switch (data[0]) { 34 36 case CI_MSG_CI_INFO: 35 - if (data[2] != 1 && data[2] != 2) 37 + if (data[2] != 1 && data[2] != MAX_CI_SLOTS) 36 38 break; 39 + 40 + slot_num = array_index_nospec(data[2] - 1, MAX_CI_SLOTS); 41 + 37 42 switch (data[1]) { 38 43 case 0: 39 - av7110->ci_slot[data[2] - 1].flags = 0; 44 + av7110->ci_slot[slot_num].flags = 0; 40 45 break; 41 46 case 1: 42 - av7110->ci_slot[data[2] - 1].flags |= CA_CI_MODULE_PRESENT; 47 + av7110->ci_slot[slot_num].flags |= CA_CI_MODULE_PRESENT; 43 48 break; 44 49 case 2: 45 - av7110->ci_slot[data[2] - 1].flags |= CA_CI_MODULE_READY; 50 + av7110->ci_slot[slot_num].flags |= CA_CI_MODULE_READY; 46 51 break; 47 52 } 48 53 break; ··· 267 262 case CA_GET_SLOT_INFO: 268 263 { 269 264 struct ca_slot_info *info = (struct ca_slot_info *)parg; 265 + unsigned int slot_num; 270 266 271 267 if (info->num < 0 || info->num > 1) { 272 268 mutex_unlock(&av7110->ioctl_mutex); 273 269 return -EINVAL; 274 270 } 275 - av7110->ci_slot[info->num].num = info->num; 276 - av7110->ci_slot[info->num].type = FW_CI_LL_SUPPORT(av7110->arm_app) ? 277 - CA_CI_LINK : CA_CI; 278 - memcpy(info, &av7110->ci_slot[info->num], sizeof(struct ca_slot_info)); 271 + slot_num = array_index_nospec(info->num, MAX_CI_SLOTS); 272 + 273 + av7110->ci_slot[slot_num].num = info->num; 274 + av7110->ci_slot[slot_num].type = FW_CI_LL_SUPPORT(av7110->arm_app) ? 275 + CA_CI_LINK : CA_CI; 276 + memcpy(info, &av7110->ci_slot[slot_num], 277 + sizeof(struct ca_slot_info)); 279 278 break; 280 279 } 281 280