Re: [PATCH 1/6] ksmbd: fix global-out-of-bounds in smb2_find_context_vals

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



2023-05-10 20:04 GMT+09:00, 張智諺 <cc85nod@xxxxxxxxx>:
> Hi  Sergey Senozhatsky,
> Let me take an example to make sure what condition we should add.
>
> Before patching, if the tag is "ExtA" and the values of create_context
> fields are following:
> - next - 24
> - name_len - 8
> - name_off - 16
> In this situation, the large `if` condition will be passed:
> ```
> if ((next & 0x7) != 0 ||
>     ...
>     ((u64)value_off + value_len > cc_len))
>     return ERR_PTR(-EINVAL);
> ```
> But when we are doing `memcmp`, the ksmbd will out-of-bound access the
> memory of the tag.
>
> However, after applying your patch, which is "name len != context len", the
> large `if` condition
> is still passwd, and the ksmbd still triggers the oob-read bug.
>
> So if we don't want to change `memcmp` to `strcmp`, what we do in the large
> `if` condition is
> make sure that the name length of create_context is equal or less than the
> length of tag, but
> we only can get the length of tag by `strlen`.
>
> Is my analysis correct? And do you have any ideas?
Yes, we need to compare length also, And we should not use strlen() to
get tag length. create context tag doesn't include null terminator.
tag length is 4 or 16. We can add tag_len argument in
smb2_find_context_vals(). So we change caller like this.

context = smb2_find_context_vals(req,

SMB2_CREATE_TIMEWARP_REQUEST, 4);

and then, In the comparison part, length is also checked.

  if (name_len == tag_len && !memcmp(name, tag, name_len))
                return cc;

Thanks.
>
> Thanks.
>
>
> Sergey Senozhatsky <senozhatsky@xxxxxxxxxxxx> 於 2023年5月9日 週二 下午12:05寫道:
>
>> On (23/05/08 21:58), Namjae Jeon wrote:
>> > 2023-05-08 10:05 GMT+09:00, Sergey Senozhatsky
>> > <senozhatsky@xxxxxxxxxxxx
>> >:
>> > > On (23/05/06 00:11), Namjae Jeon wrote:
>> > >> From: Pumpkin <cc85nod@xxxxxxxxx>
>> > >>
>> > >> If the length of CreateContext name is larger than the tag, it will
>> > >> access
>> > >> the data following the tag and trigger KASAN global-out-of-bounds.
>> > >>
>> > >> Currently all CreateContext names are defined as string, so we can
>> > >> use
>> > >> strcmp instead of memcmp to avoid the out-of-bound access.
>> > Hi Chih-Yen,
>> >
>> > Please reply to Sergey's review comment. If needed, please send v2
>> > patch after updating it.
>>
>> Chih-Yen replied privately, but let me move the discussion back to
>> public list.
>>
>> > >> +++ b/fs/ksmbd/oplock.c
>> > >> @@ -1492,7 +1492,7 @@ struct create_context
>> *smb2_find_context_vals(void
>> > >> *open_req, const char *tag)
>> > >>                    return ERR_PTR(-EINVAL);
>> > >>
>> > >>            name = (char *)cc + name_off;
>> > >> -          if (memcmp(name, tag, name_len) == 0)
>> > >> +          if (!strcmp(name, tag))
>> > >>                    return cc;
>> > >>
>> > >>            remain_len -= next;
>> > >
>> > > I'm slightly surprised that that huge `if` before memcmp() doesn't
>> catch
>> > > it
>> > >
>> > >             if ((next & 0x7) != 0 ||
>> > >                 next > remain_len ||
>> > >                 name_off != offsetof(struct create_context, Buffer)
>> > > ||
>> > >                 name_len < 4 ||
>> > >                 name_off + name_len > cc_len ||
>> > >                 (value_off & 0x7) != 0 ||
>> > >                 (value_off && (value_off < name_off + name_len)) ||
>> > >                 ((u64)value_off + value_len > cc_len))
>> > >                     return ERR_PTR(-EINVAL);
>>
>> So the question is: why doesn't this `if` catch that problem?
>> I'd rather add one extra condition here, it doesn't make a lot
>> of sense to strcmp/memcmp if we know beforehand that two strings
>> have different sizes. So a simple "name len != context len" should
>> do the trick. No?
>>
>




[Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux