Re: [PATCH v2 2/2] media: hantro: Add support for VP8 decoding on rk3288
From: Boris Brezillon
Date: Thu Jul 04 2019 - 03:19:44 EST
+Kees for the safe-array-iteratio question.
On Wed, 03 Jul 2019 16:26:46 +0200
Philipp Zabel <p.zabel@xxxxxxxxxxxxxx> wrote:
> Hi Ezequiel
>
> On Tue, 2019-07-02 at 14:00 -0300, Ezequiel Garcia wrote:
> > From: ZhiChao Yu <zhichao.yu@xxxxxxxxxxxxxx>
> >
> > Introduce VP8 decoding support in RK3288.
> >
> > Signed-off-by: ZhiChao Yu <zhichao.yu@xxxxxxxxxxxxxx>
> > Signed-off-by: Tomasz Figa <tfiga@xxxxxxxxxxxx>
> > Signed-off-by: Boris Brezillon <boris.brezillon@xxxxxxxxxxxxx>
> > Signed-off-by: Ezequiel Garcia <ezequiel@xxxxxxxxxxxxx>
>
> I have just tried this (with broken userspace) and got a crash in
> cfg_parts, see below for details:
>
> [ÂÂ114.308757] Unable to handle kernel paging request at virtual address ffff0000112b0002
> [ÂÂ114.316691] Mem abort info:
> [ÂÂ114.319503]ÂÂÂESR = 0x96000021
> [ÂÂ114.322576]ÂÂÂException class = DABT (current EL), IL = 32 bits
> [ÂÂ114.328513]ÂÂÂSET = 0, FnV = 0
> [ÂÂ114.331586]ÂÂÂEA = 0, S1PTW = 0
> [ÂÂ114.334744] Data abort info:
> [ÂÂ114.337626]ÂÂÂISV = 0, ISS = 0x00000021
> [ÂÂ114.341479]ÂÂÂCM = 0, WnR = 0
> [ÂÂ114.344466] swapper pgtable: 4k pages, 48-bit VAs, pgdp=0000000040d61000
> [ÂÂ114.351185] [ffff0000112b0002] pgd=00000000dffff003, pud=00000000dfffe003, pmd=00000000dbf36003, pte=00e8000038300707
> [ÂÂ114.361822] Internal error: Oops: 96000021 [#1] PREEMPT SMP
> [ÂÂ114.367394] Modules linked in: crct10dif_ce hantro_vpu(C) videobuf2_dma_contig v4l2_mem2mem
> [ÂÂ114.375749] Process ffmpeg (pid: 1871, stack limit = 0x0000000059d846e4)
> [ÂÂ114.382450] CPU: 1 PID: 1871 Comm: ffmpeg Tainted: GÂÂÂÂÂÂÂÂÂCÂÂÂÂÂÂÂÂ5.1.16-20190703-1 #2
> [ÂÂ114.390710] Hardware name: NXP i.MX8MQ EVK (DT)
> [ÂÂ114.395240] pstate: 40000005 (nZcv daif -PAN -UAO)
> [ÂÂ114.400042] pc : hantro_g1_vp8_dec_run+0x1178/0x18a0 [hantro_vpu]
> [ÂÂ114.406139] lr : hantro_g1_vp8_dec_run+0x1160/0x18a0 [hantro_vpu]
> [ÂÂ114.412229] sp : ffff000011ae3c10
> [ÂÂ114.415541] x29: ffff000011ae3c10 x28: ffff000008a154c8Â
> [ÂÂ114.420853] x27: 000000007033b039 x26: ffff000008a130f0Â
> [ÂÂ114.426164] x25: 000000000000000c x24: ffff000008a153f0Â
> [ÂÂ114.431474] x23: ffff800099a0d880 x22: ffff000008a13150Â
> [ÂÂ114.436785] x21: 000000000c5b88d0 x20: ffff80009b7d65a0Â
> [ÂÂ114.442096] x19: ffff800099bd3800 x18: 0000000000000010Â
> [ÂÂ114.447407] x17: 0000000000000001 x16: 0000000000000007Â
> [ÂÂ114.452717] x15: ffffffffffffffff x14: ffff000010e8c5c8Â
> [ÂÂ114.458028] x13: ffff000091ae3987 x12: ffff0000112b0002Â
> [ÂÂ114.463339] x11: ffff000010ea4000 x10: ffff000011ae3910Â
> [ÂÂ114.468649] x9 : 00000000ffffffd0 x8 : 00000000edcb88d0Â
> [ÂÂ114.473960] x7 : 0000000000000125 x6 : ffff000010e8cd60Â
> [ÂÂ114.479270] x5 : ffff000010e8c000 x4 : 0000000000000000Â
> [ÂÂ114.484580] x3 : 0000000000000002 x2 : 8127d140a3196d00Â
> [ÂÂ114.489891] x1 : 0000000000000000 x0 : 00000000e1700000Â
> [ÂÂ114.495201] Call trace:
> [ÂÂ114.497652]ÂÂhantro_g1_vp8_dec_run+0x1178/0x18a0 [hantro_vpu]
> [ÂÂ114.503401]ÂÂdevice_run+0xac/0xc0 [hantro_vpu]
> [ÂÂ114.507849]ÂÂv4l2_m2m_try_run+0x9c/0x110 [v4l2_mem2mem]
> [ÂÂ114.513077]ÂÂv4l2_m2m_request_queue+0xd4/0x130 [v4l2_mem2mem]
> [ÂÂ114.518826]ÂÂmedia_request_ioctl+0x1e8/0x2d0
> [ÂÂ114.523097]ÂÂdo_vfs_ioctl+0xc4/0x870
> [ÂÂ114.526671]ÂÂksys_ioctl+0x84/0xc0
> [ÂÂ114.529985]ÂÂ__arm64_sys_ioctl+0x28/0x40
> [ÂÂ114.533908]ÂÂel0_svc_common.constprop.0+0x98/0x170
> [ÂÂ114.538698]ÂÂel0_svc_handler+0x2c/0x40
> [ÂÂ114.542447]ÂÂel0_svc+0x8/0xc
> [ÂÂ114.545328] Code: 0b150008 b94002c3 121d7108 8b23418c (b940018c)Â
> [ÂÂ114.551421] ---[ end trace b9ad6b0f72902ba5 ]---
>
> > ---
> > Changes from v1:
> > * Place operators at the end of each line.
> > * Update to uAPI changes.
> > ---
> > drivers/staging/media/hantro/Makefile | 4 +-
> > drivers/staging/media/hantro/hantro.h | 5 +
> > drivers/staging/media/hantro/hantro_drv.c | 6 +
> > .../staging/media/hantro/hantro_g1_vp8_dec.c | 552 ++++++++++++++++++
> > drivers/staging/media/hantro/hantro_hw.h | 17 +
> > drivers/staging/media/hantro/hantro_v4l2.c | 1 +
> > drivers/staging/media/hantro/hantro_vp8.c | 188 ++++++
> > drivers/staging/media/hantro/rk3288_vpu_hw.c | 22 +-
> > 8 files changed, 793 insertions(+), 2 deletions(-)
> > create mode 100644 drivers/staging/media/hantro/hantro_g1_vp8_dec.c
> > create mode 100644 drivers/staging/media/hantro/hantro_vp8.c
> >
> [...]
> > diff --git a/drivers/staging/media/hantro/hantro_g1_vp8_dec.c b/drivers/staging/media/hantro/hantro_g1_vp8_dec.c
> > new file mode 100644
> > index 000000000000..31d31faae4aa
> > --- /dev/null
> > +++ b/drivers/staging/media/hantro/hantro_g1_vp8_dec.c
> > @@ -0,0 +1,552 @@
> [...]
> > +/* dct partition base address regs */
> > +static const struct vp8_dec_reg vp8_dec_dct_base[8] = {
> [...]
> > +/* dct partition start bits regs */
> > +static const struct vp8_dec_reg vp8_dec_dct_start_bits[8] = {
>
> So these arrays can be directly indexed with values smaller than 8 ...
>
> [...]
> > +static void cfg_parts(struct hantro_ctx *ctx,
> > + const struct v4l2_ctrl_vp8_frame_header *hdr)
> > +{
> [...]
> > + /* dct partitions base address */
> > + for (i = 0; i < hdr->num_dct_parts; i++) {
> > + u32 byte_offset = dct_part_offset + dct_size_part_size + count;
> > + u32 base_addr = byte_offset + src_dma;
> > +
> > + vp8_dec_reg_write(vpu, &vp8_dec_dct_base[i],
> > + base_addr & (~DEC_8190_ALIGN_MASK));
> > +
> > + vp8_dec_reg_write(vpu, &vp8_dec_dct_start_bits[i],
> > + (byte_offset & DEC_8190_ALIGN_MASK) * 8);
>
> ... and here they are indexed with i, which is only guaranteed to be
> smaller than hdr->num_dct_parts. num_dct_parts is passed from userspace
> via v4l2-ctrl, it can be as large as 255.
Hm, I fear we have the same problem in other places (including the
patch series adding support for H264). Kees, I wonder if there's some
kind of safe array iterator macro, something like
#define for_each_static_array_entry_safe(_array, _iter, _max_user) \
_max_user = min_t(typeof(_max_user), _max_user, ARRAY_SIZE(_array)); \
for (_iter = 0; _iter < _max_user; _iter++)
The problem with this approach is that it's papering over the real
issue, which is that hdr->num_dct_parts should be checked and the
driver/core should return an error when it's > 7 instead of silently
iterating over the 8 entries of the dct[] arrays. Static code analysis
tools can probably detect such issues too.
Any advice on how to detect such problems early on?
Thanks,
Boris