| Bug #101473 | A protential nullptr dereference of a smart pointer reported by static analyzer | ||
|---|---|---|---|
| Submitted: | 5 Nov 2020 7:55 | Modified: | 2 Dec 2020 18:25 |
| Reporter: | Ella Ma | Email Updates: | |
| Status: | Closed | Impact on me: | |
| Category: | MySQL Server: Logging | Severity: | S3 (Non-critical) |
| Version: | 8.0 | OS: | Any |
| Assigned to: | CPU Architecture: | Any | |
| Tags: | null | ||
[5 Nov 2020 7:56]
Ella Ma
Bug report generated by the static analyzer
Attachment: report-e265fd.html (text/html), 48.16 KiB.
[5 Nov 2020 13:00]
MySQL Verification Team
Hi Mr. Ma, Thank you for your bug report. However, we don't take bug reports for the unpublished releases. Please, do let us know if the errors, that you correctly observed, have crept into the official release. Every release is very, very thoroughly tested before being published, so the bug reported might not be there, in the final release. Meanwhile, we shall inform our Development of your observations.
[6 Nov 2020 3:40]
Ella Ma
Hi Verification Team, > However, we don't take bug reports for the unpublished releases. This problem can also be detected in version 8.0.22, 8.0.21 and 8.0.20. The file mentioned in the report is first introduced after version 8.0.19 and never changed then. Therefore, all versions after 8.0.19 will have the problem mentioned above. > Every release is very, very thoroughly tested before being published, so the bug reported might not be there, in the final release. Since the problem is detected by a static analyzer, chances are that it can not be triggered by dynamic test executions. But it is still worth noticing. Best regards. P.S. I am a female. Did I wrongly set my profile?
[6 Nov 2020 13:02]
MySQL Verification Team
Hi Mrs. Ma, We have checked the code in our latest release and we consider that you are correct. Verified as reported.
[6 Nov 2020 13:11]
MySQL Verification Team
Just setting the correct version.
[2 Dec 2020 18:25]
Margaret Fisher
Posted by developer: Internals, closing with no changelog entry.
[3 Dec 2020 12:32]
MySQL Verification Team
Thank you, Margaret.

Description: A nullptr dereference problem through a smart pointer caused by an unchecked, potentially nullable smart pointer. The code scanned is fetched from Github on branch `8.0` of commit ee4455a33b1. How to repeat: In function `Iterable_buffer::iterator Iterable_buffer::iterator::operator++(int)` of file `mysql-server/libbinlogevents/src/compression/iterator.cpp` on line 143. ```mysql-server/libbinlogevents/src/compression/iterator.cpp 143 Iterable_buffer::iterator Iterable_buffer::iterator::operator++(int) { 144 Iterable_buffer::iterator to_return = (*this); 145 ++(*this); 146 return to_return; 147 } ``` The copy from `*this` to `to_return` on line 144 will call the assignment operator on line 99. ```mysql-server/libbinlogevents/src/compression/iterator.cpp 99 Iterable_buffer::iterator &Iterable_buffer::iterator::operator=( 100 const Iterable_buffer::iterator &rhs) { 101 m_target = rhs.m_target; 102 if (rhs.m_reader != nullptr) { // <== ASSUME m_reader TO BE NULL 103 m_reader = std::make_unique<binary_log::Event_reader>( 104 m_target->m_decompressed_buffer, m_target->m_decompressed_buffer_size); 105 m_reader->go_to(rhs.m_reader->position()); 106 } 107 return (*this); 108 } ``` Then on line 102, the condition `rhs.m_reader != nullptr` will check the `m_reader` pointer of `*this`. **Let's assume `this->m_reader` to be nullptr here.** Then the self addition to `*this` on line 145 will call the prefix addition operator on line 122. ```mysql-server/libbinlogevents/src/compression/iterator.cpp 122 Iterable_buffer::iterator &Iterable_buffer::iterator::operator++() { 123 // advance the previous buffer length 124 if (has_next_buffer()) { ... ``` On line 124, function `has_next_buffer` is invoked. ```mysql-server/libbinlogevents/src/compression/iterator.cpp 169 bool Iterable_buffer::iterator::has_next_buffer() const { 170 if (m_reader->has_error() || // <== DEREFERENCE HERE 171 !m_reader->can_read(LOG_EVENT_MINIMAL_HEADER_LEN)) 172 return false; 173 174 return true; 175 } ``` Then, in the function `has_next_buffer` on line 169, the pointer `this->m_reader`, which was assumed to be nullptr on line 102, is dereferenced on line 170. See the attached bug report for more details. Suggested fix: Add a check to pointer m_reader before using it. If m_reader is null, return false. ``` diff --git a/libbinlogevents/src/compression/iterator.cpp b/libbinlogevents/src/compression/iterator.cpp index d795bd1da3e..cf58b349681 100644 --- a/libbinlogevents/src/compression/iterator.cpp +++ b/libbinlogevents/src/compression/iterator.cpp @@ -167,6 +167,8 @@ bool Iterable_buffer::iterator::operator!=( } bool Iterable_buffer::iterator::has_next_buffer() const { + if (!m_reader) return false; + if (m_reader->has_error() || !m_reader->can_read(LOG_EVENT_MINIMAL_HEADER_LEN)) return false; ```