2020-09-05 02:05:28

by Anant Thazhemadam

[permalink] [raw]
Subject: [Linux-kernel-mentees] [PATCH] Fix uninit-value in hci_chan_lookup_handle

When the amount of data stored in the location corresponding to
iov_iter *from is less then 4, some data seems to go uninitialized.

Updating this condition accordingly, makes sense both intuitively and
logically as well, since the other check for extreme condition done is if
len > HCI_MAX_FRAME_SIZE, which is HCI_MAX_ACL_SIZE (which is 1024) + 4;
which itself gives some idea about what must be the ideal mininum size.

Reported-and-tested by: [email protected]
Signed-off-by: Anant Thazhemadam <[email protected]>
---
If there is some explicit reason why len < 4 doesn't work, and only len < 2 works,
please do let me know.
The commit message that introduced the initial change
(512b2268156a4e15ebf897f9a883bdee153a54b7) wasn't exactly very helpful in this
respect, and I couldn't find a whole lot of discussion regarding this either.

drivers/bluetooth/hci_vhci.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/bluetooth/hci_vhci.c b/drivers/bluetooth/hci_vhci.c
index 8ab26dec5f6e..0c49821d7b98 100644
--- a/drivers/bluetooth/hci_vhci.c
+++ b/drivers/bluetooth/hci_vhci.c
@@ -159,7 +159,7 @@ static inline ssize_t vhci_get_user(struct vhci_data *data,
__u8 pkt_type, opcode;
int ret;

- if (len < 2 || len > HCI_MAX_FRAME_SIZE)
+ if (len < 4 || len > HCI_MAX_FRAME_SIZE)
return -EINVAL;

skb = bt_skb_alloc(len, GFP_KERNEL);
--
2.25.1


2020-09-25 18:02:55

by Anant Thazhemadam

[permalink] [raw]
Subject: Re: [Linux-kernel-mentees] [PATCH] Fix uninit-value in hci_chan_lookup_handle


On 05/09/20 7:34 am, Anant Thazhemadam wrote:
> When the amount of data stored in the location corresponding to
> iov_iter *from is less then 4, some data seems to go uninitialized.
>
> Updating this condition accordingly, makes sense both intuitively and
> logically as well, since the other check for extreme condition done is if
> len > HCI_MAX_FRAME_SIZE, which is HCI_MAX_ACL_SIZE (which is 1024) + 4;
> which itself gives some idea about what must be the ideal mininum size.
>
> Reported-and-tested by: [email protected]
> Signed-off-by: Anant Thazhemadam <[email protected]>
> ---
> If there is some explicit reason why len < 4 doesn't work, and only len < 2 works,
> please do let me know.
> The commit message that introduced the initial change
> (512b2268156a4e15ebf897f9a883bdee153a54b7) wasn't exactly very helpful in this
> respect, and I couldn't find a whole lot of discussion regarding this either.
>
> drivers/bluetooth/hci_vhci.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/bluetooth/hci_vhci.c b/drivers/bluetooth/hci_vhci.c
> index 8ab26dec5f6e..0c49821d7b98 100644
> --- a/drivers/bluetooth/hci_vhci.c
> +++ b/drivers/bluetooth/hci_vhci.c
> @@ -159,7 +159,7 @@ static inline ssize_t vhci_get_user(struct vhci_data *data,
> __u8 pkt_type, opcode;
> int ret;
>
> - if (len < 2 || len > HCI_MAX_FRAME_SIZE)
> + if (len < 4 || len > HCI_MAX_FRAME_SIZE)
> return -EINVAL;
>
> skb = bt_skb_alloc(len, GFP_KERNEL);
Hi,

Looks like this patch might have missed the attention of those
who can tell me if this works or why it might not.
For some more context; more details about the bug can be found at
??? https://syzkaller.appspot.com/bug?id=287b84cc1c834c7878c4193d7b18760067f10a77
I should've highlighted that in my initial mail. My apologies.

Thanks,
Anant

2020-09-26 07:47:29

by Marcel Holtmann

[permalink] [raw]
Subject: Re: [Linux-kernel-mentees] [PATCH] Fix uninit-value in hci_chan_lookup_handle

Hi Anant,

> When the amount of data stored in the location corresponding to
> iov_iter *from is less then 4, some data seems to go uninitialized.
>
> Updating this condition accordingly, makes sense both intuitively and
> logically as well, since the other check for extreme condition done is if
> len > HCI_MAX_FRAME_SIZE, which is HCI_MAX_ACL_SIZE (which is 1024) + 4;
> which itself gives some idea about what must be the ideal mininum size.
>
> Reported-and-tested by: [email protected]
> Signed-off-by: Anant Thazhemadam <[email protected]>
> ---
> If there is some explicit reason why len < 4 doesn't work, and only len < 2 works,
> please do let me know.
> The commit message that introduced the initial change
> (512b2268156a4e15ebf897f9a883bdee153a54b7) wasn't exactly very helpful in this
> respect, and I couldn't find a whole lot of discussion regarding this either.
>
> drivers/bluetooth/hci_vhci.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/bluetooth/hci_vhci.c b/drivers/bluetooth/hci_vhci.c
> index 8ab26dec5f6e..0c49821d7b98 100644
> --- a/drivers/bluetooth/hci_vhci.c
> +++ b/drivers/bluetooth/hci_vhci.c
> @@ -159,7 +159,7 @@ static inline ssize_t vhci_get_user(struct vhci_data *data,
> __u8 pkt_type, opcode;
> int ret;
>
> - if (len < 2 || len > HCI_MAX_FRAME_SIZE)
> + if (len < 4 || len > HCI_MAX_FRAME_SIZE)
> return -EINVAL;

so the minimum requirement is to have an 1 octet packet indicator. If some other functions are missing length checks, then it should be fixed there. I see that in case of HCI_VENDOR_PKT we need to check for the 2nd octet to be present, but I have no idea why you require 3 octets minimum. As I said, if so, then the other functions that get called require proper range checks.

Regards

Marcel

2020-10-01 07:16:15

by Anant Thazhemadam

[permalink] [raw]
Subject: Re: [Linux-kernel-mentees] [PATCH] Fix uninit-value in hci_chan_lookup_handle


On 26/09/20 1:16 pm, Marcel Holtmann wrote:
> Hi Anant,
>
>> When the amount of data stored in the location corresponding to
>> iov_iter *from is less then 4, some data seems to go uninitialized.
>>
>> Updating this condition accordingly, makes sense both intuitively and
>> logically as well, since the other check for extreme condition done is if
>> len > HCI_MAX_FRAME_SIZE, which is HCI_MAX_ACL_SIZE (which is 1024) + 4;
>> which itself gives some idea about what must be the ideal mininum size.
>>
>> Reported-and-tested by: [email protected]
>> Signed-off-by: Anant Thazhemadam <[email protected]>
>> ---
>> If there is some explicit reason why len < 4 doesn't work, and only len < 2 works,
>> please do let me know.
>> The commit message that introduced the initial change
>> (512b2268156a4e15ebf897f9a883bdee153a54b7) wasn't exactly very helpful in this
>> respect, and I couldn't find a whole lot of discussion regarding this either.
>>
>> drivers/bluetooth/hci_vhci.c | 2 +-
>> 1 file changed, 1 insertion(+), 1 deletion(-)
>>
>> diff --git a/drivers/bluetooth/hci_vhci.c b/drivers/bluetooth/hci_vhci.c
>> index 8ab26dec5f6e..0c49821d7b98 100644
>> --- a/drivers/bluetooth/hci_vhci.c
>> +++ b/drivers/bluetooth/hci_vhci.c
>> @@ -159,7 +159,7 @@ static inline ssize_t vhci_get_user(struct vhci_data *data,
>> __u8 pkt_type, opcode;
>> int ret;
>>
>> - if (len < 2 || len > HCI_MAX_FRAME_SIZE)
>> + if (len < 4 || len > HCI_MAX_FRAME_SIZE)
>> return -EINVAL;
> so the minimum requirement is to have an 1 octet packet indicator. If some other functions are missing length checks, then it should be fixed there. I see that in case of HCI_VENDOR_PKT we need to check for the 2nd octet to be present, but I have no idea why you require 3 octets minimum. As I said, if so, then the other functions that get called require proper range checks.
>
> Regards
>
> Marcel

Ah, I see. That makes sense, and I'm sorry for this. I just thought since
HCI_MAX_FRAME_SIZE was 4 more than 1024, min. len might have to be 4.
Taking a look at the reproducer, it becomes evident that the only reason this
patch didn't trigger an issue was because the reproducer ran with len = 3.

I don't really have a strong enough clue yet about where things are going wrong, so I'd
appreciate any guidance/insight into this, and where I should be looking. :/

Also, although the bug says it is only an uninit-value, it eventually ends up triggering
a kernel panic (looking at a log rather than a report shows that as well).

Thanks,
Anant