summaryrefslogtreecommitdiffstats
path: root/yql/essentials/minikql/mkql_string_util.cpp
diff options
context:
space:
mode:
authoratarasov5 <[email protected]>2025-05-06 15:01:42 +0300
committeratarasov5 <[email protected]>2025-05-06 15:16:42 +0300
commit0ba803a734b1c0a6c0f79beff16668302c34f3d1 (patch)
tree0d86da8eb095d8492ab8ba33bd8f193e206ad4d4 /yql/essentials/minikql/mkql_string_util.cpp
parentca377fd4336db2e4e53c1cd32160cca95766d213 (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.cpp74
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));
}