From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-qk1-f169.google.com (mail-qk1-f169.google.com [209.85.222.169]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id C17342E1EE0 for ; Wed, 17 Jun 2026 02:19:26 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.222.169 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1781662769; cv=none; b=CbYV7DQK0smN+YAR2ngR1p3nS/HwpCrTeUYePg8bx9LQPPL5qJOv1tqAuiCOeLTKqLMY53u1QarAS065jW+HcXo8Nw131H5ky54zd3XLozM59Sln9g8F/NlPF0SN5piQ4PislnjJye0Z8KERaWFtjIBoJOF7yBDBUlzSb6BmbwQ= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1781662769; c=relaxed/simple; bh=UI3cL5ENEGPS0hdo43fO33DH88kzk6rZZp7HX0r/Nqw=; h=From:To:Cc:Subject:Date:Message-ID:MIME-Version; b=V3LlrmUF5WpIlxXDEw85+MJFAsSsxEsosfHSjHN6jIYqFqmbsifw0pQJhYh+j571QjprVSbg/0CM1gNwWQJUto7+6rIZFpse9RJRvQbI88W9z1z9RIeMUosncYIN0TPnW0juLnpv5KdtyXB2w4zl/4PEa+6DiMExnTg6fkHdyGI= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=EQaXu2sF; arc=none smtp.client-ip=209.85.222.169 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="EQaXu2sF" Received: by mail-qk1-f169.google.com with SMTP id af79cd13be357-9157d3f2098so615213585a.3 for ; Tue, 16 Jun 2026 19:19:26 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1781662766; x=1782267566; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:from:to:cc:subject:date:message-id:reply-to; bh=xIfiVseohRJOgI8N6Y+Kj1p4rISAysOPz5TsHQvMuzs=; b=EQaXu2sFzHQbZQZpo3a163xE1Ao3+/8t9cB3YEJ42raJUom1luSX43MxhnTqeQwUK6 W/5BM871X/+UAq7mcJkNTCv2DKJI33brfDPA7kLZbCYjTNMhpc/yidicJdnNNauKIG4M 8gjGzOuaeoGcx3jBXMMGvhBsOrLrqMBwURuespSXjOngAypKTL/UUWwjw0WIfeHkWn0Z 7j6EIk8CU2YR52GM/hEUPTFeYZCvFAHqQEr2wOgkhRVcYwur5EbUcfQ9mX6LuTFRngO7 O6G9yWp4tl0JmUugWML+F6rC4yDO04NTvywYuecpDRhVDMNjrcrL231kENTWZt1W3xip 6Z+Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1781662766; x=1782267566; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:x-gm-gg:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to; bh=xIfiVseohRJOgI8N6Y+Kj1p4rISAysOPz5TsHQvMuzs=; b=ZvoQOczCT6RB2NkaIkWSXBxXxeVl4vU+Z3aT3xBcdWxVuwY60BDtOmFtJT6FMMghqk eOoFxdtDCvOSCeqHGvLRXL+zmVdJUaHfTWR9ALt5D/vUOe84NLA2YSEaGyigUGU8grmq mv7pRVacoJVEMV+COdTBKN86VFCMNLci04dkB/0J6HCnlCuSv28hwhDT4KD/oAGHpibs 3eqTbT/bidAQFU7w5EYhywXArWNk223gqrTmnqtXjbBgekCIYYjmsrD5u/Hes9XPw+8k QG75aWrUKdUxbmlxzdmbKppLUuSubI6N2htYuJM+tVsV37dqn0vGAXYyTlCBC5O/rT3g tVLw== X-Forwarded-Encrypted: i=1; AFNElJ8twG4HBq0ukxXR+gPApK6asU3yy2m7G1atPWP45mWACdbQ705455GlI8h0pAuS5/2Thh9e5RB/UM16B1M=@vger.kernel.org X-Gm-Message-State: AOJu0YwA8pBdCrXt/aQchtUaG4Qp4ttFvOyOKe+bCIDKINbRQoalcIl/ FaEAWI1+fI0j4DBfeUnZZBCn7Ump8t2njwEGlW27Y8Lajb7A9yHY+mZQ X-Gm-Gg: Acq92OFvuiD1dvnHajvkGNQzqOCtPu4QHW/3MgIZYl88mtipZg6jghaAMA3VMyEyaol NuisFdmFHhQ2O8jy892Imf2l7OJ0tbORAV5hDaIorDbe4M8U5T/37CzVSjMbk7tqNjske4OrYLL YCavpDvUDNbt5ZYVI1+0PL6QnkIm9DN5gTX6YyDoJaJ2Obb4TKY2/nA9QXGmIsvdjBHc7KGl4Rw 8/vRvKQoqh+mUicn12+Tq+NPyia4J+xH7Hggzdo2cLenaPW40NuQsLeEamgXIN9iUwh78OuuyKo WO+tEyvtVb+nz8owGWIGx00jgGjYRndmAkXdZj59gidumcLbsqcjqA9V+s1Hj4Vu7UN44cDGTu+ /LG/DCpqIApcgzwrkXFxWawFFrwYGASt/1SPx6BXkoUOXoRfs0fHCEWbkkZRXEtQWvab5x0Brys BINy30o8wrKGPEiHnFQo2k61f00k0xN9trPjKXA4L15JPvjDG76VcnIH7DbAEVrKWJERK+5FmNS XmIcN4wnOtBDdyJwHGQPVZhPrhBawigJ+gtOJN1fIY= X-Received: by 2002:a05:620a:44d2:b0:915:b9f6:718c with SMTP id af79cd13be357-91dbb94528bmr273219585a.28.1781662765542; Tue, 16 Jun 2026 19:19:25 -0700 (PDT) Received: from server0.tail6e7dd.ts.net (c-68-48-65-54.hsd1.mi.comcast.net. [68.48.65.54]) by smtp.gmail.com with ESMTPSA id af79cd13be357-9161a006e35sm1657646285a.28.2026.06.16.19.19.23 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 16 Jun 2026 19:19:25 -0700 (PDT) From: Michael Bommarito To: Hans Verkuil , Mauro Carvalho Chehab , Sakari Ailus , Nicolas Dufresne Cc: Laurent Pinchart , Benjamin Gaignard , Detlev Casanova , Ezequiel Garcia , Yunfei Dong , Jonas Karlman , Heiko Stuebner , Kees Cook , linux-media@vger.kernel.org, linux-rockchip@lists.infradead.org, linux-mediatek@lists.infradead.org, linux-kernel@vger.kernel.org Subject: [PATCH v3 0/9] media: bound stateless HEVC/AV1 tile counts Date: Tue, 16 Jun 2026 22:18:57 -0400 Message-ID: <20260617021906.2746743-1-michael.bommarito@gmail.com> X-Mailer: git-send-email 2.53.0 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 7bit The stateless HEVC and AV1 controls carry tile counts that several SoC decoder drivers consume as loop bounds and array indices when laying out fixed-size hardware descriptor buffers. std_validate_compound() does not bound them, so a crafted HEVC PPS or AV1 frame control can drive out-of-bounds writes and an AV1 divide-by-zero in the rkvdec, hantro, rockchip and mediatek decoders. 1-2 reject out-of-range HEVC and AV1 tile counts in std_validate_compound() (one patch per codec). For AV1 the per- dimension bound is V4L2_AV1_MAX_TILE_{COLS,ROWS} and the total is V4L2_AV1_MAX_TILE_COUNT. 3 add with bounded tile-count helpers. 4-5 use the helpers in rkvdec and hantro instead of open-coding the clamp; rkvdec also bails before indexing the hardware parameter-set table with an out-of-range HEVC PPS id. 6 guard the rockchip VPU981 AV1 divisor against tile_cols == 0 and keep the descriptor writes inside the AV1_MAX_TILES buffer. 7 reject a rockchip AV1 frame whose tile_cols * tile_rows exceeds the submitted tile group entry count or the AV1_MAX_TILES descriptor capacity, which set_tile_info() would otherwise read past or leave under-described while programming the larger geometry. 8 bound the mediatek AV1 tile-start copy. 9 KUnit coverage for the tile-count validation. Changes since v2: - Split the combined HEVC+AV1 validation into one patch per codec, each with a single Fixes tag (Benjamin Gaignard). - Move the AV1 total-tile bound into validate_av1_tile_info() using the uAPI V4L2_AV1_MAX_TILE_COUNT, instead of clamping tile_cols/tile_rows in the rockchip driver, which would have corrupted the values written to the hardware registers (Benjamin Gaignard's NACK on v2 4/6). - Add with shared bounded tile-count helpers so rkvdec and hantro no longer duplicate the clamp (Benjamin Gaignard). - New patch 7: reject a rockchip AV1 frame that claims more tiles than the submitted tile group entry array holds (set_tile_info() indexes it by tile_cols * tile_rows) or more than AV1_MAX_TILES (the hardware descriptor buffer), which would otherwise leave the hardware programmed for more tiles than the buffer describes. mediatek already guards the entry count; rockchip now guards both. checkpatch --strict: 0 errors on all nine. Patches 3 and 9 each carry one "added file ... does MAINTAINERS need updating?" warning for the new and the KUnit test file; both already fall under the existing include/media/ and drivers/media/v4l2-core/ MAINTAINERS entries, so no MAINTAINERS change is needed. (checkpatch's SPDX sub-check did not run in my environment -- spdxcheck.py needs python3-ply -- but the SPDX headers are present on both new files.) The tile-count validation is exercised with KUnit (patch 9): in-range HEVC/AV1 counts pass, out-of-range per-dimension counts and an AV1 grid whose product exceeds V4L2_AV1_MAX_TILE_COUNT are rejected, and the zero-initialised AV1 frame control that v4l2-compliance and existing userspace submit still passes. v2: https://lore.kernel.org/all/20260614155609.3107600-1-michael.bommarito@gmail.com/ Michael Bommarito (9): media: v4l2-ctrls: validate HEVC tile counts media: v4l2-ctrls: validate AV1 tile counts media: hevc: add bounded tile-count helpers media: rkvdec: bound HEVC tile loops and PPS id to the array capacity media: verisilicon: hantro: bound G2 HEVC tile loop to the buffer capacity media: verisilicon: rockchip: guard VPU981 AV1 divisor and tile buffer media: verisilicon: rockchip: reject AV1 frames exceeding the tile capacity media: mediatek: vcodec: bound AV1 tile-start copy to the array capacity media: v4l2-ctrls: add KUnit tests for compound control tile validation .../vcodec/decoder/vdec/vdec_av1_req_lat_if.c | 5 +- .../rockchip/rkvdec/rkvdec-hevc-common.c | 14 +- .../platform/rockchip/rkvdec/rkvdec-hevc.c | 7 +- .../rockchip/rkvdec/rkvdec-vdpu381-hevc.c | 2 + .../platform/verisilicon/hantro_g2_hevc_dec.c | 6 +- .../verisilicon/rockchip_vpu981_hw_av1_dec.c | 57 +++++-- drivers/media/v4l2-core/Kconfig | 12 ++ .../media/v4l2-core/v4l2-ctrls-core-test.c | 145 ++++++++++++++++++ drivers/media/v4l2-core/v4l2-ctrls-core.c | 36 +++++ include/media/v4l2-hevc.h | 41 +++++ 10 files changed, 306 insertions(+), 19 deletions(-) create mode 100644 drivers/media/v4l2-core/v4l2-ctrls-core-test.c create mode 100644 include/media/v4l2-hevc.h base-commit: e24a98d6884a6e4203a77a94f070a59fcab95208 -- 2.53.0