Skip to content

Commit 5c2fbcf

Browse files
keesopsiff
authored andcommitted
media: solo6x10: Check for out of bounds chip_id
[ Upstream commit 0fdf6323c35a134f206dcad5babb4ff488552076 ] 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: ClangBuiltLinux/linux#2144 [1] Suggested-by: Nathan Chancellor <nathan@kernel.org> Signed-off-by: Kees Cook <kees@kernel.org> Signed-off-by: Hans Verkuil <hverkuil+cisco@kernel.org> [hverkuil: fix checkpatch warning for is_tw286x] Signed-off-by: Sasha Levin <sashal@kernel.org> (cherry picked from commit 33af366211ee78e3b074ff44a16121e537e86826) Signed-off-by: Wentao Guan <guanwentao@uniontech.com>
1 parent 27242e4 commit 5c2fbcf

File tree

1 file changed

+7
-1
lines changed

1 file changed

+7
-1
lines changed

drivers/media/pci/solo6x10/solo6x10-tw28.c

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,7 @@ static const u8 tbl_tw2865_pal_template[] = {
166166
0x64, 0x51, 0x40, 0xaf, 0xFF, 0xF0, 0x00, 0xC0,
167167
};
168168

169-
#define is_tw286x(__solo, __id) (!(__solo->tw2815 & (1 << __id)))
169+
#define is_tw286x(__solo, __id) (!((__solo)->tw2815 & (1U << (__id))))
170170

171171
static u8 tw_readbyte(struct solo_dev *solo_dev, int chip_id, u8 tw6x_off,
172172
u8 tw_off)
@@ -686,6 +686,9 @@ int tw28_set_ctrl_val(struct solo_dev *solo_dev, u32 ctrl, u8 ch,
686686
chip_num = ch / 4;
687687
ch %= 4;
688688

689+
if (chip_num >= TW_NUM_CHIP)
690+
return -EINVAL;
691+
689692
if (val > 255 || val < 0)
690693
return -ERANGE;
691694

@@ -758,6 +761,9 @@ int tw28_get_ctrl_val(struct solo_dev *solo_dev, u32 ctrl, u8 ch,
758761
chip_num = ch / 4;
759762
ch %= 4;
760763

764+
if (chip_num >= TW_NUM_CHIP)
765+
return -EINVAL;
766+
761767
switch (ctrl) {
762768
case V4L2_CID_SHARPNESS:
763769
/* Only 286x has sharpness */

0 commit comments

Comments
 (0)