Skip to content

Commit 2ec69c0

Browse files
Merge pull request #1579 from bratpiorka/rrudnick_fix_IPC
add overflow checks for IPC handle size
2 parents 40a7e96 + 41e722f commit 2ec69c0

3 files changed

Lines changed: 99 additions & 3 deletions

File tree

src/ipc.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/*
22
*
3-
* Copyright (C) 2023-2025 Intel Corporation
3+
* Copyright (C) 2023-2026 Intel Corporation
44
*
55
* Under the Apache License v2.0 with LLVM Exceptions. See LICENSE.TXT.
66
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
@@ -45,6 +45,11 @@ umf_result_t umfPoolGetIPCHandleSize(umf_memory_pool_handle_t hPool,
4545
return ret;
4646
}
4747

48+
if (providerIPCHandleSize > SIZE_MAX - sizeof(umf_ipc_data_t)) {
49+
LOG_ERR("IPC handle size is too large.");
50+
return UMF_RESULT_ERROR_INVALID_ARGUMENT;
51+
}
52+
4853
*size = sizeof(umf_ipc_data_t) + providerIPCHandleSize;
4954

5055
return ret;

src/provider/provider_tracking.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/*
22
*
3-
* Copyright (C) 2023-2025 Intel Corporation
3+
* Copyright (C) 2023-2026 Intel Corporation
44
*
55
* Under the Apache License v2.0 with LLVM Exceptions. See LICENSE.TXT.
66
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
@@ -1108,6 +1108,11 @@ static umf_result_t trackingGetIpcHandle(void *provider, const void *ptr,
11081108
return ret;
11091109
}
11101110

1111+
if (ipcDataSize > SIZE_MAX - sizeof(ipc_cache_value_t)) {
1112+
LOG_ERR("upstream provider IPC handle size is too large");
1113+
return UMF_RESULT_ERROR_INVALID_ARGUMENT;
1114+
}
1115+
11111116
size_t value_size = sizeof(ipc_cache_value_t) + ipcDataSize;
11121117
cache_value = umf_ba_global_alloc(value_size);
11131118
if (!cache_value) {

test/ipcAPI.cpp

Lines changed: 87 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,17 @@
1-
// Copyright (C) 2023-2025 Intel Corporation
1+
// Copyright (C) 2023-2026 Intel Corporation
22
// Under the Apache License v2.0 with LLVM Exceptions. See LICENSE.TXT.
33
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
44
// This file contains tests for UMF pool API
55

66
#include "ipcFixtures.hpp"
77

8+
#include "ipc_internal.h"
89
#include "provider.hpp"
910

1011
#include <umf/pools/pool_disjoint.h>
1112

13+
#include <array>
14+
#include <limits>
1215
#include <shared_mutex>
1316
#include <unordered_map>
1417

@@ -122,6 +125,89 @@ provider_mock_ipc::allocations_map_type provider_mock_ipc::allocations;
122125
static umf_memory_provider_ops_t IPC_MOCK_PROVIDER_OPS =
123126
umf_test::providerMakeCOps<provider_mock_ipc, void>();
124127

128+
struct provider_mock_ipc_huge_handle : public provider_mock_ipc {
129+
struct tracking_ipc_cache_header_t {
130+
uint64_t handle_id;
131+
uint64_t ipcDataSize;
132+
};
133+
134+
umf_result_t get_name(const char **name) noexcept {
135+
*name = "mock_ipc_huge_handle";
136+
return UMF_RESULT_SUCCESS;
137+
}
138+
139+
umf_result_t ext_get_ipc_handle_size(size_t *size) noexcept {
140+
*size = std::numeric_limits<size_t>::max() -
141+
sizeof(tracking_ipc_cache_header_t) + 1;
142+
return UMF_RESULT_SUCCESS;
143+
}
144+
145+
umf_result_t ext_get_ipc_handle(const void *ptr, size_t size,
146+
void *providerIpcData) noexcept {
147+
(void)ptr;
148+
(void)size;
149+
(void)providerIpcData;
150+
ADD_FAILURE() << "IPC handle callback should not be called";
151+
return UMF_RESULT_ERROR_UNKNOWN;
152+
}
153+
};
154+
155+
static umf_memory_provider_ops_t IPC_HUGE_HANDLE_PROVIDER_OPS =
156+
umf_test::providerMakeCOps<provider_mock_ipc_huge_handle, void>();
157+
158+
static umf_test::pool_unique_handle_t createHugeHandlePool() {
159+
umf_memory_provider_handle_t hProvider = nullptr;
160+
auto ret = umfMemoryProviderCreate(&IPC_HUGE_HANDLE_PROVIDER_OPS, nullptr,
161+
&hProvider);
162+
EXPECT_EQ(ret, UMF_RESULT_SUCCESS);
163+
164+
umf_memory_pool_handle_t hPool = nullptr;
165+
ret = umfPoolCreate(umfProxyPoolOps(), hProvider, nullptr,
166+
UMF_POOL_CREATE_FLAG_OWN_PROVIDER, &hPool);
167+
if (ret != UMF_RESULT_SUCCESS) {
168+
umfMemoryProviderDestroy(hProvider);
169+
}
170+
EXPECT_EQ(ret, UMF_RESULT_SUCCESS);
171+
172+
return umf_test::pool_unique_handle_t(hPool, &umfPoolDestroy);
173+
}
174+
175+
struct ipcOverflowTest : umf_test::test {};
176+
177+
TEST_F(ipcOverflowTest, ipcHandleSizeOverflow) {
178+
auto pool = createHugeHandlePool();
179+
ASSERT_NE(pool, nullptr);
180+
181+
size_t ipcHandleSize = 0;
182+
auto ret = umfPoolGetIPCHandleSize(pool.get(), &ipcHandleSize);
183+
EXPECT_EQ(ret, UMF_RESULT_ERROR_INVALID_ARGUMENT);
184+
EXPECT_EQ(ipcHandleSize, 0u);
185+
}
186+
187+
TEST_F(ipcOverflowTest, trackingIpcCacheValueSizeOverflow) {
188+
auto pool = createHugeHandlePool();
189+
ASSERT_NE(pool, nullptr);
190+
191+
void *ptr = umfPoolMalloc(pool.get(), 4096);
192+
ASSERT_NE(ptr, nullptr);
193+
194+
umf_ipc_handler_handle_t hIPCHandler = nullptr;
195+
auto ret = umfPoolGetIPCHandler(pool.get(), &hIPCHandler);
196+
ASSERT_EQ(ret, UMF_RESULT_SUCCESS);
197+
ASSERT_NE(hIPCHandler, nullptr);
198+
199+
alignas(umf_ipc_data_t) std::array<char, sizeof(umf_ipc_data_t) + 64>
200+
ipcDataBuffer{};
201+
auto *ipcData = reinterpret_cast<umf_ipc_data_t *>(ipcDataBuffer.data());
202+
203+
ret = umfMemoryProviderGetIPCHandle(
204+
reinterpret_cast<umf_memory_provider_handle_t>(hIPCHandler), ptr, 4096,
205+
ipcData->providerIpcData);
206+
EXPECT_EQ(ret, UMF_RESULT_ERROR_INVALID_ARGUMENT);
207+
208+
umfPoolFree(pool.get(), ptr);
209+
}
210+
125211
HostMemoryAccessor hostMemoryAccessor;
126212

127213
INSTANTIATE_TEST_SUITE_P(umfIpcTestSuite, umfIpcTest,

0 commit comments

Comments
 (0)