linux-kernel-mentees.lists.linuxfoundation.org archive mirror
 help / color / mirror / Atom feed
From: Hans Verkuil <hverkuil@xs4all.nl>
To: Peilin Ye <yepeilin.cs@gmail.com>
Cc: syzkaller-bugs@googlegroups.com,
	linux-kernel-mentees@lists.linuxfoundation.org,
	linux-kernel@vger.kernel.org, linux-media@vger.kernel.org
Subject: Re: [Linux-kernel-mentees] [PATCH] v4l2-tpg: Fix global-out-of-bounds read in precalculate_color()
Date: Fri, 21 Aug 2020 12:12:28 +0200	[thread overview]
Message-ID: <eab860f3-5520-72cd-3bb1-f990f7f9ea6f@xs4all.nl> (raw)
In-Reply-To: <20200821094813.GB480216@PWN>

On 21/08/2020 11:48, Peilin Ye wrote:
> Hi Mr. Verkuil,
> 
> On Wed, Aug 19, 2020 at 04:26:28PM +0200, Hans Verkuil wrote:
>> Hi Peilin,
>>
>> On 10/08/2020 07:05, Peilin Ye wrote:
>>> precalculate_color() is reading out of `sin` since `tpg->hue` is not being
>>> properly checked. Fix it. `cos` is safe, as long as `tpg->hue` is higher
>>> than or equal to -192.
>>
>> Thank you for this patch, but there is something I don't understand, namely
>> just *how* tpg->hue can be out-of-range.
>>
>> From what I can see vivid sets hue via tpg_s_hue() when the V4L2_CID_HUE control
>> is set. But that control has a range of -128...128, so ctrl->val should always be in
>> that range.
>>
>> I would really like to know 1) what the value of tpg->hue actually is when it goes
>> out of range, and 2) who is changing it to that value. Can you do a bit more digging?
> 
> The value of `tpg->hue` was -20551. It came from the userspace, see the
> "\xb9\xaf" on line 500 of the reproducer:
> 
> https://syzkaller.appspot.com/text?tag=ReproC&x=14b49e71e00000
> 
>   NONFAILING(memcpy((void*)0x20000200, "/dev/video6\000\000", 13));
>   res = syscall(__NR_openat, 0xffffffffffffff9cul, 0x20000200ul, 2ul, 0ul);
>   if (res != -1)
>     r[0] = res;
>   NONFAILING(memcpy((void*)0x20000140,
>                     "\x4d\x43\x66\x34\xfd\x89\xb9\xaf\x0d\x59\xa2\x83\x4c\xfd"
>                      ^^^^    ^^^^    ^^^^    ^^^^^^^^
>                     "\x3e\x64\x7c\x96\xcd\x59\xf2\x3a\x18\xa3\x81\x49\x22\xc0"
>                     "\xc1\xbf\x02\xa5\x50\x5f\xcb\x48\x92\x0e\xf3\xdc\xff\x85"
>                     "\xb7\x84\x21\xab\xef\x31\x3d\xb1\xb6\x5d\xbf\x07\x8e\xee"
>                     "\x5e\x7c\x73\x32\xf4\x9d\x1e\x62\x6b\x6a\xa0\x74\x73\xe6"
>                     "\xca\x1b\xdb\x7a\xca\x76\xd8\x37\xb8\xd9",
>                     80));
>   syscall(__NR_write, r[0], 0x20000140ul, 8ul);
> 
> I guess the root cause is a race condition in the vivid test driver,
> which completely corrupted `tpg`. I see bytes like "\x4d", "\x66" and
> "\xfd" around `tpg->hue`, too.
> 
> The reproducer does two things: the above write() on /dev/video6, and a
> preadv() on /dev/video3:
> 
>   NONFAILING(*(uint64_t*)0x20000800 = 0x20000000);
>   NONFAILING(*(uint64_t*)0x20000808 = 0x1f);
>   NONFAILING(*(uint64_t*)0x20000810 = 0);
>   NONFAILING(*(uint64_t*)0x20000818 = 0);
>   NONFAILING(*(uint64_t*)0x20000820 = 0);
>   NONFAILING(*(uint64_t*)0x20000828 = 0);
>   NONFAILING(*(uint64_t*)0x20000830 = 0);
>   NONFAILING(*(uint64_t*)0x20000838 = 0);
>   NONFAILING(*(uint64_t*)0x20000840 = 0);
>   NONFAILING(*(uint64_t*)0x20000848 = 0);
>   syscall(__NR_preadv, r[1], 0x20000800ul, 5ul, 0ul);
> 
> I commented out this preadv(), then the reproducer didn't cause any
> crash. Unfortunately I don't know the code well enough in order to
> figure out exactly why...At this point of time I'd like to send you an
> v2 as you suggested, it should work as a mitigation.

Arrgh! I know what this is. /dev/video6 corresponds to the Metadata output
device of vivid, and that metadata format sets brightness, contrast,
saturation and hue:

struct vivid_meta_out_buf {
        u16     brightness;
        u16     contrast;
        u16     saturation;
        s16     hue;
};

vivid_meta_out_process() calls tpg_s_* functions to set these values. But
this is wrong, it should set the corresponding V4L2 controls instead since
calling these tpg_s_* functions bypasses all range checks. It also will
not update the controls themselves, so they are out-of-sync with the actual
values. I.e. the test pattern generator uses different values compared to
the values in the controls.

So two patches are needed:

1) a patch for include/media/tpg/v4l2-tpg.h where tpg_s_hue will clamp the
hue value to the valid range. This to prevent anyone else from setting invalid
hue values in the tpg.

2) a patch for drivers/media/test-drivers/vivid/vivid-meta-out.c where,
instead of calling the tpg_s_* functions in vivid_meta_out_process(), it
calls instead:

        v4l2_ctrl_s_ctrl(dev->brightness, meta->brightness);
        v4l2_ctrl_s_ctrl(dev->contrast, meta->contrast);
	etc.

Do patch 2 first and test with syzkaller to check that by going through the
controls this issue is resolved. Since with that approach the tpg should
always get valid hue values.

Regards,

	Hans

> 
> Thank you for the suggestion!
> 
> Peilin Ye
> 

_______________________________________________
Linux-kernel-mentees mailing list
Linux-kernel-mentees@lists.linuxfoundation.org
https://lists.linuxfoundation.org/mailman/listinfo/linux-kernel-mentees

  reply	other threads:[~2020-08-21 10:12 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-08-10  5:05 [Linux-kernel-mentees] [PATCH] v4l2-tpg: Fix global-out-of-bounds read in precalculate_color() Peilin Ye
2020-08-19 14:26 ` Hans Verkuil
2020-08-19 15:16   ` Peilin Ye
2020-08-21  9:48   ` Peilin Ye
2020-08-21 10:12     ` Hans Verkuil [this message]
2020-08-21 10:26       ` Peilin Ye
2020-08-21 12:46 ` [Linux-kernel-mentees] [PATCH v2] vivid: " Peilin Ye

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=eab860f3-5520-72cd-3bb1-f990f7f9ea6f@xs4all.nl \
    --to=hverkuil@xs4all.nl \
    --cc=linux-kernel-mentees@lists.linuxfoundation.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-media@vger.kernel.org \
    --cc=syzkaller-bugs@googlegroups.com \
    --cc=yepeilin.cs@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).