Skip to content

Conversation

ceolin
Copy link
Member

@ceolin ceolin commented Nov 21, 2023

This macros needed additional checks before invoking arch_buffer_validate.

  • size can not be less then 0. Some functions invoke this macro using signed type which will be promote to unsigned when invoking arch_buffer_validate. We need to do an early check.
  • We need to check for possible overflow, since a malicious user application could use a negative number that would be promoted to a big value that would cause a integer overflow when adding it to the buffer address, leading to invalid checks.

dcpleung
dcpleung previously approved these changes Nov 21, 2023
@henrikbrixandersen
Copy link
Member

henrikbrixandersen commented Nov 21, 2023

Hmm. So some of our APIs actually allow passing in a zero length (e.g. the EEPROM API) and this is tested (in test_zero_length_write, which now fails the test case due to these changes).

@ceolin
Copy link
Member Author

ceolin commented Nov 21, 2023

Hmm. So some of our APIs actually allow passing in a zero length (e.g. the EEPROM API) and this is tested (in test_zero_length_write, which now fails the test case due to these changes).

the problem is that arch_buffer_validate is a low level API and AFAIU in some architectures size 0 is undefined behavior. Let me check these particular use cases.

@ceolin
Copy link
Member Author

ceolin commented Nov 21, 2023

@henrikbrixandersen I end up adding a redundant check in these APIs since I think it is better to have that 0 length check in that macro to avoid any undefined behavior.

@Laczen
Copy link
Contributor

Laczen commented Nov 22, 2023

@henrikbrixandersen I end up adding a redundant check in these APIs since I think it is better to have that 0 length check in that macro to avoid any undefined behavior.

There are many api's having the same problem with the length 0 check (flash, bbram, retained_mem, ...). It would be better to correct it at the arch_buffer_validate level.

@ceolin
Copy link
Member Author

ceolin commented Nov 22, 2023

@henrikbrixandersen I end up adding a redundant check in these APIs since I think it is better to have that 0 length check in that macro to avoid any undefined behavior.

There are many api's having the same problem with the length 0 check (flash, bbram, retained_mem, ...). It would be better to correct it at the arch_buffer_validate level.

if we change arch_buffer_validate to return false we will end up with the same problem, ultimately what it means to try to read / write from a 0 length memory ?

I can remove the > 0 check there and continue how it is now, since the visible problem is mostly with huge or negative length that causes an overflow. But the fact that 0 length buffers can lead to undefined behavior in that function is really scary

@Laczen
Copy link
Contributor

Laczen commented Nov 22, 2023

@henrikbrixandersen I end up adding a redundant check in these APIs since I think it is better to have that 0 length check in that macro to avoid any undefined behavior.

There are many api's having the same problem with the length 0 check (flash, bbram, retained_mem, ...). It would be better to correct it at the arch_buffer_validate level.

if we change arch_buffer_validate to return false we will end up with the same problem, ultimately what it means to try to read / write from a 0 length memory ?

Writing/reading with 0 length memory in all cases I know means: do nothing. A well written driver will not do anything in this case. In practice this will never be used. I don't understand why all drivers try to catch this early, this is just extra code that is never used in practice.

The arch_buffer_validate routine should accept len = 0 for any void *data. With data = NULL it should only accept len = 0.

This macros needed additional checks before invoking
arch_buffer_validate.

- size can not be less then 0. Some functions invoke this macro
  using signed type which will be promote to unsigned when invoking
  arch_buffer_validate. We need to do an early check.
- We need to check for possible overflow, since a malicious user
  application could use a negative number that would be promoted
  to a big value that would cause a integer overflow when adding it
  to the buffer address, leading to invalid checks.

Signed-off-by: Flavio Ceolin <flavio.ceolin@intel.com>
@ceolin ceolin force-pushed the userspace/buffer_validation branch from b584c13 to 3fcb96a Compare December 9, 2023 18:57
@ceolin
Copy link
Member Author

ceolin commented Dec 9, 2023

@henrikbrixandersen I end up adding a redundant check in these APIs since I think it is better to have that 0 length check in that macro to avoid any undefined behavior.

There are many api's having the same problem with the length 0 check (flash, bbram, retained_mem, ...). It would be better to correct it at the arch_buffer_validate level.

if we change arch_buffer_validate to return false we will end up with the same problem, ultimately what it means to try to read / write from a 0 length memory ?

Writing/reading with 0 length memory in all cases I know means: do nothing. A well written driver will not do anything in this case. In practice this will never be used. I don't understand why all drivers try to catch this early, this is just extra code that is never used in practice.

The arch_buffer_validate routine should accept len = 0 for any void *data. With data = NULL it should only accept len = 0.

I have dropped the check "> 0" since there are APIs relying on it. Instead I changed ">= 0" that fix the real problem because some functions invoke this macro using signed type which will be promote to unsigned when invoking arch_buffer_validate.

@carlescufi carlescufi merged commit 899d4f9 into zephyrproject-rtos:main Dec 11, 2023
@Laczen
Copy link
Contributor

Laczen commented Dec 22, 2023

@ceolin This change seems to have triggered many Coverity CID issues.

@finikorg
Copy link
Contributor

Same for me, size is usually unsigned.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Status: Done
Development

Successfully merging this pull request may close these issues.

7 participants