Skip to content

Commit fc4cb53

Browse files
authored
streamlookup: Fix UAF when GetAsyncInputData called before Bootstrap or after PassAway (#11865)
1 parent f9076b7 commit fc4cb53

File tree

1 file changed

+30
-23
lines changed

1 file changed

+30
-23
lines changed

ydb/library/yql/dq/actors/input_transforms/dq_input_transform_lookup.cpp

Lines changed: 30 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,10 @@ using TOutputRowColumnOrder = std::vector<std::pair<EOutputRowItemSource, ui64>>
2222

2323
//Design note: Base implementation is optimized for wide channels
2424
class TInputTransformStreamLookupBase
25-
: public NActors::TActorBootstrapped<TInputTransformStreamLookupBase>
25+
: public NActors::TActor<TInputTransformStreamLookupBase>
2626
, public NYql::NDq::IDqComputeActorAsyncInput
2727
{
28+
using TActor = NActors::TActor<TInputTransformStreamLookupBase>;
2829
public:
2930
TInputTransformStreamLookupBase(
3031
std::shared_ptr<NKikimr::NMiniKQL::TScopedAlloc> alloc,
@@ -47,7 +48,8 @@ class TInputTransformStreamLookupBase
4748
size_t cacheLimit,
4849
std::chrono::seconds cacheTtl
4950
)
50-
: Alloc(alloc)
51+
: TActor(&TInputTransformStreamLookupBase::StateFunc)
52+
, Alloc(alloc)
5153
, HolderFactory(holderFactory)
5254
, TypeEnv(typeEnv)
5355
, InputIndex(inputIndex)
@@ -86,26 +88,6 @@ class TInputTransformStreamLookupBase
8688
Free();
8789
}
8890

89-
void Bootstrap() {
90-
Become(&TInputTransformStreamLookupBase::StateFunc);
91-
NDq::IDqAsyncIoFactory::TLookupSourceArguments lookupSourceArgs {
92-
.Alloc = Alloc,
93-
.KeyTypeHelper = KeyTypeHelper,
94-
.ParentId = SelfId(),
95-
.TaskCounters = TaskCounters,
96-
.LookupSource = Settings.GetRightSource().GetLookupSource(),
97-
.KeyType = LookupKeyType,
98-
.PayloadType = LookupPayloadType,
99-
.TypeEnv = TypeEnv,
100-
.HolderFactory = HolderFactory,
101-
.MaxKeysInRequest = 1000 // TODO configure me
102-
};
103-
auto guard = Guard(*Alloc);
104-
auto [lookupSource, lookupSourceActor] = Factory->CreateDqLookupSource(Settings.GetRightSource().GetProviderName(), std::move(lookupSourceArgs));
105-
MaxKeysInRequest = lookupSource->GetMaxSupportedKeysInRequest();
106-
LookupSourceId = RegisterWithSameMailbox(lookupSourceActor);
107-
KeysForLookup = std::make_shared<IDqAsyncLookupSource::TUnboxedValueMap>(MaxKeysInRequest, KeyTypeHelper->GetValueHash(), KeyTypeHelper->GetValueEqual());
108-
}
10991
protected:
11092
virtual NUdf::EFetchStatus FetchWideInputValue(NUdf::TUnboxedValue* inputRowItems) = 0;
11193
virtual void PushOutputValue(NKikimr::NMiniKQL::TUnboxedValueBatch& batch, NUdf::TUnboxedValue* outputRowItems) = 0;
@@ -199,6 +181,7 @@ class TInputTransformStreamLookupBase
199181
}
200182

201183
void PassAway() final {
184+
InputFlowFetchStatus = NUdf::EFetchStatus::Finish;
202185
Send(LookupSourceId, new NActors::TEvents::TEvPoison{});
203186
Free();
204187
}
@@ -225,14 +208,38 @@ class TInputTransformStreamLookupBase
225208
}
226209
}
227210

211+
std::shared_ptr<IDqAsyncLookupSource::TUnboxedValueMap> GetKeysForLookup() { // must be called with mkql allocator
212+
if (!KeysForLookup) {
213+
Y_ENSURE(SelfId());
214+
Y_ENSURE(!LookupSourceId);
215+
NDq::IDqAsyncIoFactory::TLookupSourceArguments lookupSourceArgs {
216+
.Alloc = Alloc,
217+
.KeyTypeHelper = KeyTypeHelper,
218+
.ParentId = SelfId(),
219+
.TaskCounters = TaskCounters,
220+
.LookupSource = Settings.GetRightSource().GetLookupSource(),
221+
.KeyType = LookupKeyType,
222+
.PayloadType = LookupPayloadType,
223+
.TypeEnv = TypeEnv,
224+
.HolderFactory = HolderFactory,
225+
.MaxKeysInRequest = 1000 // TODO configure me
226+
};
227+
auto [lookupSource, lookupSourceActor] = Factory->CreateDqLookupSource(Settings.GetRightSource().GetProviderName(), std::move(lookupSourceArgs));
228+
MaxKeysInRequest = lookupSource->GetMaxSupportedKeysInRequest();
229+
LookupSourceId = RegisterWithSameMailbox(lookupSourceActor);
230+
KeysForLookup = std::make_shared<IDqAsyncLookupSource::TUnboxedValueMap>(MaxKeysInRequest, KeyTypeHelper->GetValueHash(), KeyTypeHelper->GetValueEqual());
231+
}
232+
return KeysForLookup;
233+
}
234+
228235
i64 GetAsyncInputData(NKikimr::NMiniKQL::TUnboxedValueBatch& batch, TMaybe<TInstant>&, bool& finished, i64 freeSpace) final {
229236
Y_UNUSED(freeSpace);
230237
auto startCycleCount = GetCycleCountFast();
231238
auto guard = BindAllocator();
232239

233240
DrainReadyQueue(batch);
234241

235-
if (InputFlowFetchStatus != NUdf::EFetchStatus::Finish && KeysForLookup->empty()) {
242+
if (InputFlowFetchStatus != NUdf::EFetchStatus::Finish && GetKeysForLookup()->empty()) {
236243
Y_DEBUG_ABORT_UNLESS(AwaitingQueue.empty());
237244
NUdf::TUnboxedValue* inputRowItems;
238245
NUdf::TUnboxedValue inputRow = HolderFactory.CreateDirectArrayHolder(InputRowType->GetElementsCount(), inputRowItems);

0 commit comments

Comments
 (0)