On Thu Dec 11 19:00:35 2025 -0800, Kees Cook wrote:
> Clang with CONFIG_UBSAN_SHIFT=y noticed a condition where a signed type
> (literal "1" is an "int") could end up being shifted beyond 32 bits,
> so instrumentation was added (and due to the double is_tw286x() call
> seen via inlining), Clang decides the second one must now be undefined
> behavior and elides the rest of the function[1]. This is a known problem
> with Clang (that is still being worked on), but we can avoid the entire
> problem by actually checking the existing max chip ID, and now there is
> no runtime instrumentation added at all since everything is known to be
> within bounds.
>
> Additionally use an unsigned value for the shift to remove the
> instrumentation even without the explicit bounds checking.
>
> Link: https://github.com/ClangBuiltLinux/linux/issues/2144 [1]
> Suggested-by: Nathan Chancellor <[email protected]>
> Signed-off-by: Kees Cook <[email protected]>
> Signed-off-by: Hans Verkuil <[email protected]>
> [hverkuil: fix checkpatch warning for is_tw286x]
Patch committed.
Thanks,
Hans Verkuil
drivers/media/pci/solo6x10/solo6x10-tw28.c | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
---
diff --git a/drivers/media/pci/solo6x10/solo6x10-tw28.c
b/drivers/media/pci/solo6x10/solo6x10-tw28.c
index 1b7c22a9bc94..8f53946c6792 100644
--- a/drivers/media/pci/solo6x10/solo6x10-tw28.c
+++ b/drivers/media/pci/solo6x10/solo6x10-tw28.c
@@ -166,7 +166,7 @@ static const u8 tbl_tw2865_pal_template[] = {
0x64, 0x51, 0x40, 0xaf, 0xFF, 0xF0, 0x00, 0xC0,
};
-#define is_tw286x(__solo, __id) (!(__solo->tw2815 & (1 << __id)))
+#define is_tw286x(__solo, __id) (!((__solo)->tw2815 & (1U << (__id))))
static u8 tw_readbyte(struct solo_dev *solo_dev, int chip_id, u8 tw6x_off,
u8 tw_off)
@@ -686,6 +686,9 @@ int tw28_set_ctrl_val(struct solo_dev *solo_dev, u32 ctrl,
u8 ch,
chip_num = ch / 4;
ch %= 4;
+ if (chip_num >= TW_NUM_CHIP)
+ return -EINVAL;
+
if (val > 255 || val < 0)
return -ERANGE;
@@ -758,6 +761,9 @@ int tw28_get_ctrl_val(struct solo_dev *solo_dev, u32 ctrl,
u8 ch,
chip_num = ch / 4;
ch %= 4;
+ if (chip_num >= TW_NUM_CHIP)
+ return -EINVAL;
+
switch (ctrl) {
case V4L2_CID_SHARPNESS:
/* Only 286x has sharpness */
_______________________________________________
linuxtv-commits mailing list -- [email protected]
To unsubscribe send an email to [email protected]