Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix issue #722 Bitset accesses memory out of bounds #723

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
78 changes: 44 additions & 34 deletions include/etl/private/bitset_legacy.h
Original file line number Diff line number Diff line change
Expand Up @@ -283,6 +283,10 @@ namespace etl
size_t index;
element_type mask;

if (position >= Active_Bits)
{
return false;
}
if (Number_Of_Elements == 0)
{
return false;
Expand Down Expand Up @@ -320,28 +324,31 @@ namespace etl
size_t index;
element_type bit;

if (Number_Of_Elements == 0)
{
return *this;
}
else if (Number_Of_Elements == 1)
{
index = 0;
bit = element_type(1) << position;
}
else
if (position < Active_Bits)
{
index = position >> etl::log2<Bits_Per_Element>::value;
bit = element_type(1) << (position & (Bits_Per_Element - 1));
}
if (Number_Of_Elements == 0)
{
return *this;
}
else if (Number_Of_Elements == 1)
{
index = 0;
bit = element_type(1) << position;
}
else
{
index = position >> etl::log2<Bits_Per_Element>::value;
bit = element_type(1) << (position & (Bits_Per_Element - 1));
}

if (value)
{
pdata[index] |= bit;
}
else
{
pdata[index] &= ~bit;
if (value)
{
pdata[index] |= bit;
}
else
{
pdata[index] &= ~bit;
}
}

return *this;
Expand Down Expand Up @@ -516,22 +523,25 @@ namespace etl
size_t index;
element_type bit;

if (Number_Of_Elements == 0)
{
return *this;
}
else if (Number_Of_Elements == 1)
{
index = 0;
bit = element_type(1) << position;
}
else
if (position < Active_Bits)
{
index = position >> etl::log2<Bits_Per_Element>::value;
bit = element_type(1) << (position & (Bits_Per_Element - 1));
}
if (Number_Of_Elements == 0)
{
return *this;
}
else if (Number_Of_Elements == 1)
{
index = 0;
bit = element_type(1) << position;
}
else
{
index = position >> etl::log2<Bits_Per_Element>::value;
bit = element_type(1) << (position & (Bits_Per_Element - 1));
}

pdata[index] &= ~bit;
pdata[index] &= ~bit;
}

return *this;
}
Expand Down
42 changes: 34 additions & 8 deletions include/etl/private/bitset_new.h
Original file line number Diff line number Diff line change
Expand Up @@ -1921,8 +1921,11 @@ namespace etl
//*************************************************************************
ETL_CONSTEXPR14 bitset<Active_Bits, TElement, false>& set(size_t position, bool value = true) ETL_NOEXCEPT
{
ibitset.set(buffer, Number_Of_Elements, position, value);
clear_unused_bits_in_msb();
if (position < Active_Bits)
{
ibitset.set(buffer, Number_Of_Elements, position, value);
clear_unused_bits_in_msb();
}

return *this;
}
Expand Down Expand Up @@ -2051,7 +2054,10 @@ namespace etl
//*************************************************************************
ETL_CONSTEXPR14 bitset<Active_Bits, TElement, false>& reset(size_t position) ETL_NOEXCEPT
{
ibitset.reset(buffer, Number_Of_Elements, position);
if (position < Active_Bits)
{
ibitset.reset(buffer, Number_Of_Elements, position);
}
return *this;
}

Expand All @@ -2061,7 +2067,14 @@ namespace etl
//*************************************************************************
ETL_CONSTEXPR14 bool test(size_t position) const ETL_NOEXCEPT
{
return ibitset.test(buffer, Number_Of_Elements, position);
if (position < Active_Bits)
{
return ibitset.test(buffer, Number_Of_Elements, position);
}
else
{
return false;
}
}

//*************************************************************************
Expand Down Expand Up @@ -3633,8 +3646,11 @@ namespace etl
//*************************************************************************
ETL_CONSTEXPR14 bitset_ext<Active_Bits, TElement, false>& set(size_t position, bool value = true) ETL_NOEXCEPT
{
ibitset.set(pbuffer, Number_Of_Elements, position, value);
clear_unused_bits_in_msb();
if (position < Active_Bits)
{
ibitset.set(pbuffer, Number_Of_Elements, position, value);
clear_unused_bits_in_msb();
}

return *this;
}
Expand Down Expand Up @@ -3763,7 +3779,10 @@ namespace etl
//*************************************************************************
ETL_CONSTEXPR14 bitset_ext<Active_Bits, TElement, false>& reset(size_t position) ETL_NOEXCEPT
{
ibitset.reset(pbuffer, Number_Of_Elements, position);
if (position < Active_Bits)
{
ibitset.reset(pbuffer, Number_Of_Elements, position);
}
return *this;
}

Expand All @@ -3773,7 +3792,14 @@ namespace etl
//*************************************************************************
ETL_CONSTEXPR14 bool test(size_t position) const ETL_NOEXCEPT
{
return ibitset.test(pbuffer, Number_Of_Elements, position);
if (position < Active_Bits)
{
return ibitset.test(pbuffer, Number_Of_Elements, position);
}
else
{
return false;
}
}

//*************************************************************************
Expand Down
31 changes: 31 additions & 0 deletions test/test_bitset_legacy.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -547,6 +547,16 @@ namespace
}
}

//*************************************************************************
TEST(test_position_set_invalid_position_does_not_corrupt_memory_github_issue_722)
{
etl::bitset<12> data;
ETL_MAYBE_UNUSED uint16_t some_memory = 0;

data.set(17);
CHECK_EQUAL(some_memory, 0);
}

//*************************************************************************
TEST(test_reset)
{
Expand Down Expand Up @@ -616,6 +626,27 @@ namespace
}
}

//*************************************************************************
TEST(test_position_reset_invalid_position_does_not_corrupt_memory_github_issue_722)
{
etl::bitset<12> data;
ETL_MAYBE_UNUSED uint16_t some_memory = 0xFFFFU;

data.reset(17);
CHECK_EQUAL(some_memory, 0xFFFFU);
}

//*************************************************************************
TEST(test_position_test_invalid_position_returns_always_false_github_issue_722)
{
etl::bitset<12> data;
ETL_MAYBE_UNUSED uint16_t some_memory = 0xFFFFU;

data.set(13);
CHECK_FALSE(data.test(13));
CHECK_FALSE(data.test(17));
}

//*************************************************************************
TEST(test_index_operator_read)
{
Expand Down
31 changes: 31 additions & 0 deletions test/test_bitset_new_default_element_type.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1256,6 +1256,16 @@ namespace
}
}

//*************************************************************************
TEST(test_position_set_invalid_position_does_not_corrupt_memory_github_issue_722)
{
etl::bitset<12> data;
ETL_MAYBE_UNUSED uint16_t some_memory = 0;

data.set(17);
CHECK_EQUAL(some_memory, 0);
}

//*************************************************************************
TEST(test_reset)
{
Expand Down Expand Up @@ -1305,6 +1315,27 @@ namespace
}
}

//*************************************************************************
TEST(test_position_reset_invalid_position_does_not_corrupt_memory_github_issue_722)
{
etl::bitset<12> data;
ETL_MAYBE_UNUSED uint16_t some_memory = 0xFFFFU;

data.reset(17);
CHECK_EQUAL(some_memory, 0xFFFFU);
}

//*************************************************************************
TEST(test_position_test_invalid_position_returns_always_false_github_issue_722)
{
etl::bitset<12> data;
ETL_MAYBE_UNUSED uint16_t some_memory = 0xFFFFU;

data.set(13);
CHECK_FALSE(data.test(13));
CHECK_FALSE(data.test(17));
}

//*************************************************************************
TEST(test_index_operator_read)
{
Expand Down
31 changes: 31 additions & 0 deletions test/test_bitset_new_explicit_single_element_type.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -637,6 +637,16 @@ namespace
}
}

//*************************************************************************
TEST(test_position_set_invalid_position_does_not_corrupt_memory_github_issue_722)
{
etl::bitset<12, uint16_t> data;
ETL_MAYBE_UNUSED uint16_t some_memory = 0;

data.set(17);
CHECK_EQUAL(some_memory, 0);
}

//*************************************************************************
ETL_CONSTEXPR14 etl::bitset<64, int64_t> test_reset_helper()
{
Expand Down Expand Up @@ -699,6 +709,27 @@ namespace
}
}

//*************************************************************************
TEST(test_position_reset_invalid_position_does_not_corrupt_memory_github_issue_722)
{
etl::bitset<12, uint16_t> data;
ETL_MAYBE_UNUSED uint16_t some_memory = 0xFFFFU;

data.reset(17);
CHECK_EQUAL(some_memory, 0xFFFFU);
}

//*************************************************************************
TEST(test_position_test_invalid_position_returns_always_false_github_issue_722)
{
etl::bitset<12, uint16_t> data;
ETL_MAYBE_UNUSED uint16_t some_memory = 0xFFFFU;

data.set(13);
CHECK_FALSE(data.test(13));
CHECK_FALSE(data.test(17));
}

//*************************************************************************
TEST(test_index_operator_read)
{
Expand Down
34 changes: 34 additions & 0 deletions test/test_bitset_new_ext_default_element_type.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1265,6 +1265,17 @@ namespace
}
}

//*************************************************************************
TEST(test_position_set_invalid_position_does_not_corrupt_memory_github_issue_722)
{
etl::bitset_ext<12>::buffer_type buffer;
ETL_MAYBE_UNUSED uint16_t some_memory = 0;
etl::bitset_ext<12> data(buffer);

data.set(17);
CHECK_EQUAL(some_memory, 0);
}

//*************************************************************************
TEST(test_reset)
{
Expand Down Expand Up @@ -1318,6 +1329,29 @@ namespace
}
}

//*************************************************************************
TEST(test_position_reset_invalid_position_does_not_corrupt_memory_github_issue_722)
{
etl::bitset_ext<12>::buffer_type buffer;
ETL_MAYBE_UNUSED uint16_t some_memory = 0xFFFFU;
etl::bitset_ext<12> data(buffer);

data.reset(17);
CHECK_EQUAL(some_memory, 0xFFFFU);
}

//*************************************************************************
TEST(test_position_test_invalid_position_returns_always_false_github_issue_722)
{
etl::bitset_ext<12>::buffer_type buffer;
ETL_MAYBE_UNUSED uint16_t some_memory = 0xFFFFU;
etl::bitset_ext<12> data(buffer);

data.set(13);
CHECK_FALSE(data.test(13));
CHECK_FALSE(data.test(17));
}

//*************************************************************************
TEST(test_index_operator_read)
{
Expand Down
Loading
Loading