This is an automated email from the ASF dual-hosted git repository.

dataroaring pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/doris.git


The following commit(s) were added to refs/heads/master by this push:
     new 4ccdd65bf6 [Fix](array) fix mysql_row_buffer may use after free when 
reserve() delete original address in dynamic_mode (#11395)
4ccdd65bf6 is described below

commit 4ccdd65bf667447c37d256d6b299fc60cfd19f78
Author: lihangyu <[email protected]>
AuthorDate: Mon Aug 1 22:52:19 2022 +0800

    [Fix](array) fix mysql_row_buffer may use after free when reserve() delete 
original address in dynamic_mode (#11395)
    
    ```
    if (!_dynamic_mode) {
            int8store(_len_pos, _pos - _len_pos - 8);
            _len_pos = nullptr;
    }
    ```
    
    _len_pos may be pointed to the pos which already deleted in reserve, 
int8store will asign value to the freed address,
    and lead to use after free when build in ASAN.So I changed _len_pos to the 
offset of _buf
---
 be/src/util/mysql_row_buffer.cpp | 15 ++++++++-------
 be/src/util/mysql_row_buffer.h   |  2 +-
 2 files changed, 9 insertions(+), 8 deletions(-)

diff --git a/be/src/util/mysql_row_buffer.cpp b/be/src/util/mysql_row_buffer.cpp
index 33844d0d54..dce4a478b6 100644
--- a/be/src/util/mysql_row_buffer.cpp
+++ b/be/src/util/mysql_row_buffer.cpp
@@ -67,7 +67,7 @@ MysqlRowBuffer::MysqlRowBuffer()
           _buf(_default_buf),
           _buf_size(sizeof(_default_buf)),
           _dynamic_mode(0),
-          _len_pos(nullptr) {}
+          _len_pos(0) {}
 
 MysqlRowBuffer::~MysqlRowBuffer() {
     if (_buf != _default_buf) {
@@ -79,7 +79,7 @@ void MysqlRowBuffer::open_dynamic_mode() {
     if (!_dynamic_mode) {
         *_pos++ = NEXT_EIGHT_BYTE;
         // write length when dynamic mode close
-        _len_pos = _pos;
+        _len_pos = (_pos - _buf);
         _pos = _pos + 8;
     }
     _dynamic_mode++;
@@ -88,9 +88,10 @@ void MysqlRowBuffer::open_dynamic_mode() {
 void MysqlRowBuffer::close_dynamic_mode() {
     _dynamic_mode--;
 
+    // _buf + _len_pos is the position to write length
     if (!_dynamic_mode) {
-        int8store(_len_pos, _pos - _len_pos - 8);
-        _len_pos = nullptr;
+        int8store((_buf + _len_pos), _pos - (_buf + _len_pos) - 8);
+        _len_pos = 0;
     }
 }
 
@@ -113,14 +114,14 @@ int MysqlRowBuffer::reserve(int64_t size) {
         LOG(ERROR) << "alloc memory failed. size = " << alloc_size;
         return -1;
     }
-
-    memcpy(new_buf, _buf, _pos - _buf);
+    size_t offset = _pos - _buf;
+    memcpy(new_buf, _buf, offset);
 
     if (_buf != _default_buf) {
         delete[] _buf;
     }
 
-    _pos = new_buf + (_pos - _buf);
+    _pos = new_buf + offset;
     _buf = new_buf;
     _buf_size = alloc_size;
 
diff --git a/be/src/util/mysql_row_buffer.h b/be/src/util/mysql_row_buffer.h
index 5d00ae9f68..54dc05bec6 100644
--- a/be/src/util/mysql_row_buffer.h
+++ b/be/src/util/mysql_row_buffer.h
@@ -124,7 +124,7 @@ private:
     char _default_buf[4096];
 
     int _dynamic_mode;
-    char* _len_pos;
+    uint64_t _len_pos;
 };
 
 } // namespace doris


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to