Skip to content

Commit f37aacd

Browse files
authored
Merge pull request #3676 from medismailben/stable/20210726
[lldb/plugin] Fix heap-use-after-free in ScriptedProcess::ReadMemory
2 parents 85d27d1 + 5a97a02 commit f37aacd

File tree

8 files changed

+120
-3
lines changed

8 files changed

+120
-3
lines changed

lldb/bindings/interface/SBData.i

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,10 @@ public:
9696
void
9797
SetData (lldb::SBError& error, const void *buf, size_t size, lldb::ByteOrder endian, uint8_t addr_size);
9898

99+
void
100+
SetDataWithOwnership (lldb::SBError& error, const void *buf, size_t size,
101+
lldb::ByteOrder endian, uint8_t addr_size);
102+
99103
bool
100104
Append (const SBData& rhs);
101105

lldb/bindings/python/static-binding/LLDBWrapPython.cpp

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19090,6 +19090,81 @@ SWIGINTERN PyObject *_wrap_SBData_SetData(PyObject *SWIGUNUSEDPARM(self), PyObje
1909019090
}
1909119091

1909219092

19093+
SWIGINTERN PyObject *_wrap_SBData_SetDataWithOwnership(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
19094+
PyObject *resultobj = 0;
19095+
lldb::SBData *arg1 = (lldb::SBData *) 0 ;
19096+
lldb::SBError *arg2 = 0 ;
19097+
void *arg3 = (void *) 0 ;
19098+
size_t arg4 ;
19099+
lldb::ByteOrder arg5 ;
19100+
uint8_t arg6 ;
19101+
void *argp1 = 0 ;
19102+
int res1 = 0 ;
19103+
void *argp2 = 0 ;
19104+
int res2 = 0 ;
19105+
int val5 ;
19106+
int ecode5 = 0 ;
19107+
unsigned char val6 ;
19108+
int ecode6 = 0 ;
19109+
PyObject *swig_obj[5] ;
19110+
19111+
if (!SWIG_Python_UnpackTuple(args, "SBData_SetDataWithOwnership", 5, 5, swig_obj)) SWIG_fail;
19112+
res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_lldb__SBData, 0 | 0 );
19113+
if (!SWIG_IsOK(res1)) {
19114+
SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "SBData_SetDataWithOwnership" "', argument " "1"" of type '" "lldb::SBData *""'");
19115+
}
19116+
arg1 = reinterpret_cast< lldb::SBData * >(argp1);
19117+
res2 = SWIG_ConvertPtr(swig_obj[1], &argp2, SWIGTYPE_p_lldb__SBError, 0 );
19118+
if (!SWIG_IsOK(res2)) {
19119+
SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "SBData_SetDataWithOwnership" "', argument " "2"" of type '" "lldb::SBError &""'");
19120+
}
19121+
if (!argp2) {
19122+
SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "SBData_SetDataWithOwnership" "', argument " "2"" of type '" "lldb::SBError &""'");
19123+
}
19124+
arg2 = reinterpret_cast< lldb::SBError * >(argp2);
19125+
{
19126+
if (PythonString::Check(swig_obj[2])) {
19127+
PythonString str(PyRefType::Borrowed, swig_obj[2]);
19128+
arg3 = (void*)str.GetString().data();
19129+
arg4 = str.GetSize();
19130+
}
19131+
else if(PythonByteArray::Check(swig_obj[2])) {
19132+
PythonByteArray bytearray(PyRefType::Borrowed, swig_obj[2]);
19133+
arg3 = (void*)bytearray.GetBytes().data();
19134+
arg4 = bytearray.GetSize();
19135+
}
19136+
else if (PythonBytes::Check(swig_obj[2])) {
19137+
PythonBytes bytes(PyRefType::Borrowed, swig_obj[2]);
19138+
arg3 = (void*)bytes.GetBytes().data();
19139+
arg4 = bytes.GetSize();
19140+
}
19141+
else {
19142+
PyErr_SetString(PyExc_ValueError, "Expecting a buffer");
19143+
return NULL;
19144+
}
19145+
}
19146+
ecode5 = SWIG_AsVal_int(swig_obj[3], &val5);
19147+
if (!SWIG_IsOK(ecode5)) {
19148+
SWIG_exception_fail(SWIG_ArgError(ecode5), "in method '" "SBData_SetDataWithOwnership" "', argument " "5"" of type '" "lldb::ByteOrder""'");
19149+
}
19150+
arg5 = static_cast< lldb::ByteOrder >(val5);
19151+
ecode6 = SWIG_AsVal_unsigned_SS_char(swig_obj[4], &val6);
19152+
if (!SWIG_IsOK(ecode6)) {
19153+
SWIG_exception_fail(SWIG_ArgError(ecode6), "in method '" "SBData_SetDataWithOwnership" "', argument " "6"" of type '" "uint8_t""'");
19154+
}
19155+
arg6 = static_cast< uint8_t >(val6);
19156+
{
19157+
SWIG_PYTHON_THREAD_BEGIN_ALLOW;
19158+
(arg1)->SetDataWithOwnership(*arg2,(void const *)arg3,arg4,arg5,arg6);
19159+
SWIG_PYTHON_THREAD_END_ALLOW;
19160+
}
19161+
resultobj = SWIG_Py_Void();
19162+
return resultobj;
19163+
fail:
19164+
return NULL;
19165+
}
19166+
19167+
1909319168
SWIGINTERN PyObject *_wrap_SBData_Append(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
1909419169
PyObject *resultobj = 0;
1909519170
lldb::SBData *arg1 = (lldb::SBData *) 0 ;
@@ -82267,6 +82342,7 @@ static PyMethodDef SwigMethods[] = {
8226782342
{ "SBData_GetDescription", _wrap_SBData_GetDescription, METH_VARARGS, "SBData_GetDescription(SBData self, SBStream description, lldb::addr_t base_addr) -> bool"},
8226882343
{ "SBData_ReadRawData", _wrap_SBData_ReadRawData, METH_VARARGS, "SBData_ReadRawData(SBData self, SBError error, lldb::offset_t offset, void * buf) -> size_t"},
8226982344
{ "SBData_SetData", _wrap_SBData_SetData, METH_VARARGS, "SBData_SetData(SBData self, SBError error, void const * buf, lldb::ByteOrder endian, uint8_t addr_size)"},
82345+
{ "SBData_SetDataWithOwnership", _wrap_SBData_SetDataWithOwnership, METH_VARARGS, "SBData_SetDataWithOwnership(SBData self, SBError error, void const * buf, lldb::ByteOrder endian, uint8_t addr_size)"},
8227082346
{ "SBData_Append", _wrap_SBData_Append, METH_VARARGS, "SBData_Append(SBData self, SBData rhs) -> bool"},
8227182347
{ "SBData_CreateDataFromCString", _wrap_SBData_CreateDataFromCString, METH_VARARGS, "SBData_CreateDataFromCString(lldb::ByteOrder endian, uint32_t addr_byte_size, char const * data) -> SBData"},
8227282348
{ "SBData_CreateDataFromUInt64Array", _wrap_SBData_CreateDataFromUInt64Array, METH_VARARGS, "SBData_CreateDataFromUInt64Array(lldb::ByteOrder endian, uint32_t addr_byte_size, uint64_t * array) -> SBData"},

lldb/bindings/python/static-binding/lldb.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3798,6 +3798,10 @@ def SetData(self, error, buf, endian, addr_size):
37983798
r"""SetData(SBData self, SBError error, void const * buf, lldb::ByteOrder endian, uint8_t addr_size)"""
37993799
return _lldb.SBData_SetData(self, error, buf, endian, addr_size)
38003800

3801+
def SetDataWithOwnership(self, error, buf, endian, addr_size):
3802+
r"""SetDataWithOwnership(SBData self, SBError error, void const * buf, lldb::ByteOrder endian, uint8_t addr_size)"""
3803+
return _lldb.SBData_SetDataWithOwnership(self, error, buf, endian, addr_size)
3804+
38013805
def Append(self, rhs):
38023806
r"""Append(SBData self, SBData rhs) -> bool"""
38033807
return _lldb.SBData_Append(self, rhs)

lldb/include/lldb/API/SBData.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,9 @@ class LLDB_API SBData {
8383
void SetData(lldb::SBError &error, const void *buf, size_t size,
8484
lldb::ByteOrder endian, uint8_t addr_size);
8585

86+
void SetDataWithOwnership(lldb::SBError &error, const void *buf, size_t size,
87+
lldb::ByteOrder endian, uint8_t addr_size);
88+
8689
// see SetData() for why we don't have Append(const void* buf, size_t size)
8790
bool Append(const SBData &rhs);
8891

lldb/source/API/SBData.cpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -374,6 +374,25 @@ void SBData::SetData(lldb::SBError &error, const void *buf, size_t size,
374374
}
375375
}
376376

377+
void SBData::SetDataWithOwnership(lldb::SBError &error, const void *buf,
378+
size_t size, lldb::ByteOrder endian,
379+
uint8_t addr_size) {
380+
LLDB_RECORD_DUMMY(
381+
void, SBData, SetData,
382+
(lldb::SBError &, const void *, size_t, lldb::ByteOrder, uint8_t, bool),
383+
error, buf, size, endian, addr_size, copy);
384+
385+
lldb::DataBufferSP buffer_sp = std::make_shared<DataBufferHeap>(buf, size);
386+
387+
if (!m_opaque_sp.get())
388+
m_opaque_sp = std::make_shared<DataExtractor>(buf, size, endian, addr_size);
389+
else {
390+
m_opaque_sp->SetData(buffer_sp);
391+
m_opaque_sp->SetByteOrder(endian);
392+
m_opaque_sp->SetAddressByteSize(addr_size);
393+
}
394+
}
395+
377396
bool SBData::Append(const SBData &rhs) {
378397
LLDB_RECORD_METHOD(bool, SBData, Append, (const lldb::SBData &), rhs);
379398

lldb/test/API/functionalities/scripted_process/TestScriptedProcess.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,6 @@ def create_stack_skinny_corefile(self, file):
139139

140140
@skipUnlessDarwin
141141
@skipIfOutOfTreeDebugserver
142-
@skipIfAsan # rdar://85954489
143142
def test_launch_scripted_process_stack_frames(self):
144143
"""Test that we can launch an lldb scripted process from the command
145144
line, check its process ID and read string from memory."""

lldb/test/API/functionalities/scripted_process/stack_core_scripted_process.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,9 @@ def read_memory_at_address(self, addr: int, size: int) -> lldb.SBData:
4343
if error.Fail():
4444
return data
4545

46-
data.SetData(error, bytes_read, self.corefile_target.GetByteOrder(),
47-
self.corefile_target.GetAddressByteSize())
46+
data.SetDataWithOwnership(error, bytes_read,
47+
self.corefile_target.GetByteOrder(),
48+
self.corefile_target.GetAddressByteSize())
4849

4950
return data
5051

lldb/test/API/python_api/sbdata/TestSBData.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,17 @@ def test_byte_order_and_address_byte_size(self):
4141
self.assertEqual(addr, 0x8877665544332211);
4242

4343
@skipIfReproducer # SBData::SetData is not instrumented.
44+
def test_byte_order_and_address_byte_size_with_ownership(self):
45+
"""Test the SBData::SetDataWithOwnership() to ensure the byte order
46+
and address byte size are obeyed even when source date is released"""
47+
addr_data = b'\x11\x22\x33\x44\x55\x66\x77\x88'
48+
error = lldb.SBError()
49+
data = lldb.SBData()
50+
data.SetDataWithOwnership(error, addr_data, lldb.eByteOrderBig, 8)
51+
del addr_data
52+
addr = data.GetAddress(error, 0)
53+
self.assertEqual(addr, 0x1122334455667788);
54+
4455
def test_with_run_command(self):
4556
"""Test the SBData APIs."""
4657
self.build()

0 commit comments

Comments
 (0)