From bbc21cf063ffc1686573ffc7dbcd47bbc8b71ffa Mon Sep 17 00:00:00 2001 From: Norman Feske Date: Tue, 5 May 2020 12:44:34 +0200 Subject: [PATCH] util/bit_array.h: remove use of memset and memcpy This makes the code less dependent on functions considered unsafe. Fixes #3748 --- repos/base/include/util/bit_allocator.h | 2 +- repos/base/include/util/bit_array.h | 48 ++++++++++++++++--------- repos/os/include/os/packet_allocator.h | 13 +++---- 3 files changed, 39 insertions(+), 24 deletions(-) diff --git a/repos/base/include/util/bit_allocator.h b/repos/base/include/util/bit_allocator.h index 573dfc220..bcd74920a 100644 --- a/repos/base/include/util/bit_allocator.h +++ b/repos/base/include/util/bit_allocator.h @@ -55,7 +55,7 @@ class Genode::Bit_allocator class Range_conflict : Exception {}; Bit_allocator() { _reserve(BITS, BITS_ALIGNED - BITS); } - Bit_allocator(const Bit_allocator & o) : _array(o._array) { } + Bit_allocator(Bit_allocator const &other) : _array(other._array) { } /** * Allocate block of bits diff --git a/repos/base/include/util/bit_array.h b/repos/base/include/util/bit_array.h index dbecc9a45..f3d6e87b5 100644 --- a/repos/base/include/util/bit_array.h +++ b/repos/base/include/util/bit_array.h @@ -20,7 +20,7 @@ #include namespace Genode { - + class Bit_array_base; template class Bit_array; } @@ -44,9 +44,9 @@ class Genode::Bit_array_base private: - unsigned _bit_cnt; - unsigned _word_cnt; - addr_t *_words; + unsigned const _bit_cnt; + unsigned const _word_cnt = _bit_cnt / BITS_PER_WORD; + addr_t * const _words; addr_t _word(addr_t index) const { return index / BITS_PER_WORD; } @@ -76,10 +76,10 @@ class Genode::Bit_array_base { _check_range(index, width); - addr_t rest, word, mask; + addr_t rest; do { - word = _word(index); - mask = _mask(index, width, rest); + addr_t const word = _word(index); + addr_t const mask = _mask(index, width, rest); if (free) { if ((_words[word] & mask) != mask) @@ -96,16 +96,27 @@ class Genode::Bit_array_base } while (rest); } + /* + * Noncopyable + */ + Bit_array_base(Bit_array_base const &); + Bit_array_base &operator = (Bit_array_base const &); + public: - Bit_array_base(unsigned bits, addr_t *addr, bool clear) - : _bit_cnt(bits), - _word_cnt(_bit_cnt / BITS_PER_WORD), - _words(addr) + /** + * Constructor + * + * \param ptr pointer to array used as backing store for the bits. + * The array must be initialized with zeros. + * + * \throw Invalid_bit_count + */ + Bit_array_base(unsigned bits, addr_t *ptr) + : + _bit_cnt(bits), _words(ptr) { if (!bits || bits % BITS_PER_WORD) throw Invalid_bit_count(); - - if (clear) memset(_words, 0, sizeof(addr_t)*_word_cnt); } /** @@ -146,13 +157,16 @@ class Genode::Bit_array : public Bit_array_base static_assert(BITS % BITS_PER_WORD == 0, "Count of bits need to be word aligned!"); - addr_t _array[_WORDS]; + struct Array { addr_t values[_WORDS]; } _array { }; public: - Bit_array() : Bit_array_base(BITS, _array, true) { } - Bit_array(const Bit_array & o) : Bit_array_base(BITS, _array, false) { - memcpy(&_array, &o._array, sizeof(_array)); } + Bit_array() : Bit_array_base(BITS, _array.values) { } + + Bit_array(Bit_array const &other) + : + Bit_array_base(BITS, _array.values), _array(other._array) + { } }; #endif /* _INCLUDE__UTIL__BIT_ARRAY_H_ */ diff --git a/repos/os/include/os/packet_allocator.h b/repos/os/include/os/packet_allocator.h index 67709fb9a..b94f1a74c 100644 --- a/repos/os/include/os/packet_allocator.h +++ b/repos/os/include/os/packet_allocator.h @@ -39,7 +39,7 @@ class Genode::Packet_allocator : public Genode::Range_allocator Allocator *_md_alloc; /* meta-data allocator */ size_t _block_size; /* granularity of packet allocations */ - void *_bits = nullptr; /* memory chunk containing the bits */ + addr_t *_bits = nullptr; /* memory chunk containing the bits */ Bit_array_base *_array = nullptr; /* bit array managing available blocks */ addr_t _base = 0; /* allocation base */ addr_t _next = 0; /* next free bit index */ @@ -76,11 +76,12 @@ class Genode::Packet_allocator : public Genode::Range_allocator { if (_base || _array) return -1; - _base = base; - _bits = _md_alloc->alloc(_block_cnt(size)/8); - _array = new (_md_alloc) Bit_array_base(_block_cnt(size), - (addr_t*)_bits, - true); + size_t const number_of_bytes = _block_cnt(size)/8; + _base = base; + _bits = (addr_t *)_md_alloc->alloc(number_of_bytes); + memset(_bits, 0, number_of_bytes); + + _array = new (_md_alloc) Bit_array_base(_block_cnt(size), _bits); return 0; }