diff options
| author | atarasov5 <[email protected]> | 2025-05-06 15:01:42 +0300 |
|---|---|---|
| committer | atarasov5 <[email protected]> | 2025-05-06 15:16:42 +0300 |
| commit | 0ba803a734b1c0a6c0f79beff16668302c34f3d1 (patch) | |
| tree | 0d86da8eb095d8492ab8ba33bd8f193e206ad4d4 /yql/essentials/minikql/mkql_string_util.cpp | |
| parent | ca377fd4336db2e4e53c1cd32160cca95766d213 (diff) | |
YQL-19767: Introduce MKQL allocator address sanitizing
Здесь поддержал только out of bounds access и use after free. Отложенное использование памяти и тд буду делать потом
commit_hash:2a3fd472b626762ff7c8b7b0bc1285af50c511cf
Diffstat (limited to 'yql/essentials/minikql/mkql_string_util.cpp')
| -rw-r--r-- | yql/essentials/minikql/mkql_string_util.cpp | 74 |
1 files changed, 51 insertions, 23 deletions
diff --git a/yql/essentials/minikql/mkql_string_util.cpp b/yql/essentials/minikql/mkql_string_util.cpp index 78adacc231d..e9604c06924 100644 --- a/yql/essentials/minikql/mkql_string_util.cpp +++ b/yql/essentials/minikql/mkql_string_util.cpp @@ -1,5 +1,7 @@ #include "mkql_string_util.h" +#include <util/generic/scope.h> + namespace NKikimr { namespace NMiniKQL { @@ -31,19 +33,26 @@ NUdf::TUnboxedValuePod AppendString(const NUdf::TUnboxedValuePod value, const NU return result; } else { if (value.IsString()) { - auto str = value.AsStringValue(); - const ui32 offset = ref.Data() - str.Data(); - if (str.Size() == valueRef.Size() + offset) { - if (str.TryExpandOn(ref.Size())) { - std::memcpy(str.Data() + offset + valueRef.Size(), ref.Data(), ref.Size()); - return NUdf::TUnboxedValuePod(std::move(str), newSize, offset); + auto str = value.AsRawStringValue(); + const char* strData = str->Data(); + const char* refData = ref.Data(); + // Check if ref.Data() is within the memory range of str + if (refData >= strData && refData < strData + str->Size()) { + const ui32 offset = refData - strData; + if (str->Size() == valueRef.Size() + offset) { + if (str->TryExpandOn(ref.Size())) { + std::memcpy(str->Data() + offset + valueRef.Size(), ref.Data(), ref.Size()); + return NUdf::TUnboxedValuePod(NYql::NUdf::TStringValue(std::move(str)), newSize, offset); + } } } } - auto data = NUdf::TStringValue::AllocateData(newSize, newSize + newSize / 2); NUdf::TStringValue str(data); - data->UnRef(); + Y_DEFER { + data->ReleaseRef(); + value.DeleteUnreferenced(); + }; std::memcpy(str.Data(), valueRef.Data(), valueRef.Size()); std::memcpy(str.Data() + valueRef.Size(), ref.Data(), ref.Size()); return NUdf::TUnboxedValuePod(std::move(str)); @@ -69,10 +78,12 @@ NUdf::TUnboxedValuePod PrependString(const NUdf::TStringRef ref, const NUdf::TUn } else { auto data = NUdf::TStringValue::AllocateData(newSize, newSize + newSize / 2); NUdf::TStringValue str(data); - data->UnRef(); + Y_DEFER { + data->ReleaseRef(); + value.DeleteUnreferenced(); + }; std::memcpy(str.Data(), ref.Data(), ref.Size()); std::memcpy(str.Data() + ref.Size(), valueRef.Data(), valueRef.Size()); - value.DeleteUnreferenced(); return NUdf::TUnboxedValuePod(std::move(str)); } } @@ -96,23 +107,31 @@ NUdf::TUnboxedValuePod ConcatStrings(const NUdf::TUnboxedValuePod first, const N return result; } else { if (first.IsString()) { - auto str = first.AsStringValue(); - const ui32 offset = leftRef.Data() - str.Data(); - if (str.Size() == leftRef.Size() + offset) { - if (str.TryExpandOn(rightRef.Size())) { - std::memcpy(str.Data() + offset + leftRef.Size(), rightRef.Data(), rightRef.Size()); - second.DeleteUnreferenced(); - return NUdf::TUnboxedValuePod(std::move(str), newSize, offset); + auto str = first.AsRawStringValue(); + const char* strData = str->Data(); + const char* leftRefData = leftRef.Data(); + // Check if leftRef.Data() is within the memory range of str + if (leftRefData >= strData && leftRefData < strData + str->Size()) { + const ui32 offset = leftRefData - strData; + if (str->Size() == leftRef.Size() + offset) { + if (str->TryExpandOn(rightRef.Size())) { + std::memcpy(str->Data() + offset + leftRef.Size(), rightRef.Data(), rightRef.Size()); + second.DeleteUnreferenced(); + return NUdf::TUnboxedValuePod(NUdf::TStringValue(str), newSize, offset); + } } } } auto data = NUdf::TStringValue::AllocateData(newSize, newSize + newSize / 2); NUdf::TStringValue str(data); - data->UnRef(); + Y_DEFER { + data->ReleaseRef(); + second.DeleteUnreferenced(); + first.DeleteUnreferenced(); + }; std::memcpy(str.Data(), leftRef.Data(), leftRef.Size()); std::memcpy(str.Data() + leftRef.Size(), rightRef.Data(), rightRef.Size()); - second.DeleteUnreferenced(); return NUdf::TUnboxedValuePod(std::move(str)); } } @@ -134,13 +153,22 @@ NUdf::TUnboxedValuePod SubString(const NUdf::TUnboxedValuePod value, ui32 offset value.DeleteUnreferenced(); return result; } else { - auto old = value.AsStringValue(); - if (const auto newOffset = ui32(ref.Data() - old.Data()) + offset; NUdf::TUnboxedValuePod::OffsetLimit > newOffset) - return NUdf::TUnboxedValuePod(std::move(old), newSize, newOffset); + auto old = value.AsRawStringValue(); + const char* oldData = old->Data(); + const char* refData = ref.Data(); + // Check if ref.Data() is within the memory range of old + if (refData >= oldData && refData < oldData + old->Size()) { + if (const auto newOffset = ui32(refData - oldData) + offset; NUdf::TUnboxedValuePod::OffsetLimit > newOffset) { + return NUdf::TUnboxedValuePod(NUdf::TStringValue(old), newSize, newOffset); + } + } auto data = NUdf::TStringValue::AllocateData(newSize, newSize + (newSize >> 1U)); NUdf::TStringValue str(data); - data->UnRef(); + Y_DEFER { + data->ReleaseRef(); + value.DeleteUnreferenced(); + }; std::memcpy(str.Data(), ref.Data() + offset, newSize); return NUdf::TUnboxedValuePod(std::move(str)); } |
