Skip to content

Commit a6123da

Browse files
author
Petter Reinholdtsen
committed
Removed artificial limits using PATH_MAX.
Rewrote all code using PATH_MAX to instead dynamically allocate the required buffers. As the actually max path length depend on the file system used, it is not a good idea to pretend a compiled in buffer limit will work everywhere. This also fixes build problems detected on GNU Hurd.
1 parent 01badbe commit a6123da

File tree

6 files changed

+165
-58
lines changed

6 files changed

+165
-58
lines changed

src/tbb/cgroup_info.h

Lines changed: 47 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -149,26 +149,43 @@ class cgroup_info {
149149
}
150150

151151
static bool try_read_cgroup_v1_num_cpus_from(const char* dir, int& num_cpus) {
152-
char path[PATH_MAX] = {0};
153-
if (std::snprintf(path, PATH_MAX, "%s/cpu.cfs_quota_us", dir) < 0)
152+
std::size_t pathlen = strlen(dir) + 30;
153+
char *path = (char*)calloc(pathlen, 1);
154+
if (std::snprintf(path, pathlen, "%s/cpu.cfs_quota_us", dir) < 0) {
155+
free(path);
156+
path = NULL;
154157
return false; // Failed to create path
158+
}
155159

156160
unique_file_t fd(std::fopen(path, "r"), &close_file);
157-
if (!fd)
161+
if (!fd) {
162+
free(path);
163+
path = NULL;
158164
return false;
165+
}
159166

160167
long long cpu_quota = 0;
161-
if (std::fscanf(fd.get(), "%lld", &cpu_quota) != 1)
168+
if (std::fscanf(fd.get(), "%lld", &cpu_quota) != 1) {
169+
free(path);
170+
path = NULL;
162171
return false;
172+
}
163173

164174
if (-1 == cpu_quota) {
165175
num_cpus = unlimited_num_cpus; // -1 quota means maximum available CPUs
176+
free(path);
177+
path = NULL;
166178
return true;
167179
}
168180

169-
if (std::snprintf(path, PATH_MAX, "%s/cpu.cfs_period_us", dir) < 0)
181+
if (std::snprintf(path, pathlen, "%s/cpu.cfs_period_us", dir) < 0) {
182+
free(path);
183+
path = NULL;
170184
return false; // Failed to create path;
185+
}
171186
fd.reset(std::fopen(path, "r"));
187+
free(path);
188+
path = NULL;
172189
if (!fd)
173190
return false;
174191

@@ -181,11 +198,17 @@ class cgroup_info {
181198
}
182199

183200
static bool try_read_cgroup_v2_num_cpus_from(const char* dir, int& num_cpus) {
184-
char path[PATH_MAX] = {0};
185-
if (std::snprintf(path, PATH_MAX, "%s/cpu.max", dir) < 0)
201+
std::size_t pathlen = strlen(dir) + 30;
202+
char *path = (char*)calloc(pathlen, 1);
203+
if (std::snprintf(path, pathlen, "%s/cpu.max", dir) < 0) {
204+
free(path);
205+
path = NULL;
186206
return false; // Failed to create path
207+
}
187208

188209
unique_file_t fd(std::fopen(path, "r"), &close_file);
210+
free(path);
211+
path = NULL;
189212
if (!fd)
190213
return false;
191214

@@ -222,14 +245,19 @@ class cgroup_info {
222245

223246
static int parse_cgroup_entry(const char* mnt_dir, process_cgroup_data& pcd) {
224247
int num_cpus = error_value; // Initialize to an impossible value
225-
char dir[PATH_MAX] = {0};
226-
if (std::snprintf(dir, PATH_MAX, "%s/%s", mnt_dir, pcd.relative_path) >= 0) {
248+
std::size_t dirlen = strlen(mnt_dir) + strlen(pcd.relative_path) + 2;
249+
char *dir = (char*)calloc(dirlen, 1);
250+
if (std::snprintf(dir, dirlen, "%s/%s", mnt_dir, pcd.relative_path) >= 0) {
227251
if (try_read_cgroup_num_cpus_from(dir, num_cpus, pcd.version)) {
252+
free(dir);
253+
dir = NULL;
228254
return num_cpus;
229255
}
230256
}
231-
232-
return try_read_cgroup_num_cpus_from(mnt_dir, num_cpus, pcd.version) ? num_cpus : error_value;
257+
num_cpus = try_read_cgroup_num_cpus_from(mnt_dir, num_cpus, pcd.version) ? num_cpus : error_value;
258+
free(dir);
259+
dir = NULL;
260+
return num_cpus;
233261
}
234262

235263
static bool is_cpu_restriction_possible(process_cgroup_data& pcd) {
@@ -276,17 +304,22 @@ class cgroup_info {
276304
static int try_common_cgroup_mount_path(const process_cgroup_data& pcd,
277305
const cgroup_settings& cg_cfg) {
278306
int num_cpus = error_value;
279-
char dir[PATH_MAX] = {0};
307+
std::size_t dirlen = (strlen(pcd.relative_path)
308+
+ strlen(cg_cfg.sys_fs_cgroup_dir_path)
309+
+ 25);
310+
char *dir = (char*)calloc(dirlen, 1);
280311
__TBB_ASSERT(*pcd.relative_path, nullptr);
281-
if (0 <= std::snprintf(dir, PATH_MAX, "%s/%s", cg_cfg.sys_fs_cgroup_dir_path,
312+
if (0 <= std::snprintf(dir, dirlen, "%s/%s", cg_cfg.sys_fs_cgroup_dir_path,
282313
pcd.relative_path))
283314
try_read_cgroup_num_cpus_from(dir, num_cpus, pcd.version);
284315

285316
if (error_value == num_cpus && pcd.version == process_cgroup_data::cgroup_version::v2) {
286-
if (0 <= std::snprintf(dir, PATH_MAX, "%s/%s", "/sys/fs/cgroup/unified",
317+
if (0 <= std::snprintf(dir, dirlen, "%s/%s", "/sys/fs/cgroup/unified",
287318
pcd.relative_path))
288319
try_read_cgroup_v2_num_cpus_from(dir, num_cpus);
289320
}
321+
free(dir);
322+
dir = NULL;
290323
return num_cpus;
291324
}
292325

src/tbb/dynamic_link.cpp

Lines changed: 66 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -45,9 +45,6 @@
4545
#include <wintrust.h>
4646
#pragma comment (lib, "wintrust") // Link with the Wintrust.lib file.
4747
#endif
48-
#ifndef PATH_MAX
49-
#define PATH_MAX MAX_PATH
50-
#endif
5148
#else /* _WIN32 */
5249
#include <dlfcn.h>
5350
#include <unistd.h>
@@ -177,7 +174,7 @@ namespace r1 {
177174
break;
178175
case dl_buff_too_small:
179176
TBB_FPRINTF(stderr, "%s An internal buffer representing a path to dynamically loaded "
180-
"module is small. Consider compiling with larger value for PATH_MAX macro.\n",
177+
"module is small.\n",
181178
prefix);
182179
break;
183180
case dl_unload_fail:
@@ -340,12 +337,15 @@ namespace r1 {
340337
static std::once_flag init_dl_data_state;
341338

342339
static struct ap_data_t {
343-
char _path[PATH_MAX+1];
340+
char *_path;
341+
std::size_t _capacity;
344342
std::size_t _len;
345343
} ap_data;
346344

347345
static void init_ap_data() {
348346
#if _WIN32
347+
ap_data._capacity = MAX_PATH;
348+
ap_data._path = (char*)calloc(ap_data._capacity, 1);
349349
// Get handle of our DLL first.
350350
HMODULE handle;
351351
BOOL brc = GetModuleHandleEx(
@@ -356,30 +356,45 @@ namespace r1 {
356356
if ( !brc ) { // Error occurred.
357357
int err = GetLastError();
358358
DYNAMIC_LINK_WARNING( dl_sys_fail, "GetModuleHandleEx", err );
359+
free(ap_data._path);
360+
ap_data._path = NULL;
361+
ap_data._capacity = 0;
359362
return;
360363
}
361364
// Now get path to our DLL.
362-
DWORD drc = GetModuleFileName( handle, ap_data._path, static_cast< DWORD >( PATH_MAX ) );
365+
DWORD drc = GetModuleFileName( handle, ap_data._path, static_cast< DWORD >( ap_data._capacity ) );
363366
if ( drc == 0 ) { // Error occurred.
364367
int err = GetLastError();
365368
DYNAMIC_LINK_WARNING( dl_sys_fail, "GetModuleFileName", err );
369+
free(ap_data._path);
370+
ap_data._path = NULL;
371+
ap_data._capacity = 0;
366372
return;
367373
}
368-
if ( drc >= PATH_MAX ) { // Buffer too short.
374+
if ( drc >= ap_data._capacity ) { // Buffer too short.
369375
DYNAMIC_LINK_WARNING( dl_buff_too_small );
376+
free(ap_data._path);
377+
ap_data._path = NULL;
378+
ap_data._capacity = 0;
370379
return;
371380
}
372381
// Find the position of the last backslash.
373382
char *backslash = std::strrchr( ap_data._path, '\\' );
374383

375384
if ( !backslash ) { // Backslash not found.
376385
__TBB_ASSERT_EX( backslash != nullptr, "Unbelievable.");
386+
free(ap_data._path);
387+
ap_data._path = NULL;
388+
ap_data._capacity = 0;
377389
return;
378390
}
379391
__TBB_ASSERT_EX( backslash >= ap_data._path, "Unbelievable.");
380392
ap_data._len = (std::size_t)(backslash - ap_data._path) + 1;
381393
*(backslash+1) = 0;
382394
#else
395+
// Initial capacity, double until large enough
396+
ap_data._capacity = 4096;
397+
ap_data._path = (char*)calloc(ap_data._capacity, 1);
383398
// There is an use case, when we want to find TBB library, not just some shared object
384399
// providing "dynamic_link" symbol (it can be shared object that directly includes
385400
// dynamic_link.cpp). For this case we use a public TBB symbol. Searching for public symbol
@@ -397,6 +412,9 @@ namespace r1 {
397412
if ( !res ) {
398413
char const * err = dlerror();
399414
DYNAMIC_LINK_WARNING( dl_sys_fail, "dladdr", err );
415+
free(ap_data._path);
416+
ap_data._path = NULL;
417+
ap_data._capacity = 0;
400418
return;
401419
} else {
402420
__TBB_ASSERT_EX( dlinfo.dli_fname!=nullptr, "Unbelievable." );
@@ -416,9 +434,14 @@ namespace r1 {
416434
ap_data._len = 0;
417435
} else {
418436
// The library path is relative so get the current working directory
419-
if ( !getcwd( ap_data._path, sizeof(ap_data._path)/sizeof(ap_data._path[0]) ) ) {
420-
DYNAMIC_LINK_WARNING( dl_buff_too_small );
421-
return;
437+
while ( !getcwd( ap_data._path, ap_data._capacity) ) {
438+
free(ap_data._path);
439+
ap_data._capacity *= 2;
440+
ap_data._path = (char*)calloc(ap_data._capacity, 1);
441+
if (NULL == ap_data._path) {
442+
DYNAMIC_LINK_WARNING( dl_buff_too_small );
443+
return;
444+
}
422445
}
423446
ap_data._len = std::strlen( ap_data._path );
424447
ap_data._path[ap_data._len++]='/';
@@ -427,9 +450,12 @@ namespace r1 {
427450

428451
if ( fname_len>0 ) {
429452
ap_data._len += fname_len;
430-
if ( ap_data._len>PATH_MAX ) {
453+
if ( ap_data._len>ap_data._capacity ) {
431454
DYNAMIC_LINK_WARNING( dl_buff_too_small );
432455
ap_data._len=0;
456+
free(ap_data._path);
457+
ap_data._path = NULL;
458+
ap_data._capacity = 0;
433459
return;
434460
}
435461
std::strncpy( ap_data._path+rc, dlinfo.dli_fname, fname_len );
@@ -463,7 +489,9 @@ namespace r1 {
463489
if ( full_len < len ) {
464490
__TBB_ASSERT_EX( ap_data._path[ap_data._len] == 0, nullptr );
465491
__TBB_ASSERT_EX( std::strlen(ap_data._path) == ap_data._len, nullptr );
466-
std::strncpy( path, ap_data._path, ap_data._len + 1 );
492+
// No need for strncpy, test above confirmed enough space
493+
// and do not need zero padding at the end.
494+
std::strcpy( path, ap_data._path);
467495
__TBB_ASSERT_EX( path[ap_data._len] == 0, nullptr );
468496
std::strncat( path, name, len - ap_data._len );
469497
__TBB_ASSERT_EX( std::strlen(path) == full_len, nullptr );
@@ -662,14 +690,17 @@ namespace r1 {
662690
* occurs, in which case the error is optionally reported.
663691
*/
664692
bool has_valid_signature(const char* filepath, const std::size_t length) {
665-
__TBB_ASSERT_EX(length <= PATH_MAX, "Too small buffer for path conversion");
666-
wchar_t wfilepath[PATH_MAX] = {0};
693+
std::size_t pathlen = strlen(filepath)+1;
694+
wchar_t *wfilepath = (wchar_t*)calloc(pathlen, sizeof(wchar_t));
667695
{
668696
std::mbstate_t state{};
669697
const char* ansi_filepath = filepath; // mbsrtowcs moves original pointer
670698
const size_t num_converted = mbsrtowcs(wfilepath, &ansi_filepath, length, &state);
671-
if (num_converted == std::size_t(-1))
699+
if (num_converted == std::size_t(-1)) {
700+
free (wfilepath);
701+
wfilepath = NULL;
672702
return false;
703+
}
673704
}
674705
WINTRUST_FILE_INFO fdata;
675706
std::memset(&fdata, 0, sizeof(fdata));
@@ -699,6 +730,8 @@ namespace r1 {
699730
pWVTData.dwStateAction = WTD_STATEACTION_CLOSE; // Release WVT state data
700731
(void)WinVerifyTrust(NULL, &pgActionID, &pWVTData);
701732

733+
free (wfilepath);
734+
wfilepath = NULL;
702735
return ERROR_SUCCESS == rc;
703736
}
704737
#endif // _WIN32 && !__TBB_SKIP_DEPENDENCY_SIGNATURE_VERIFICATION
@@ -710,42 +743,50 @@ namespace r1 {
710743
dynamic_link_handle library_handle = nullptr;
711744
#if __TBB_DYNAMIC_LOAD_ENABLED
712745
const char* path = library;
713-
std::size_t const len = PATH_MAX + 1;
714-
char absolute_path[ len ] = {0};
746+
std::size_t len = abs_path( library, NULL, 1);
747+
char *absolute_path = (char*)calloc(len, 1);
715748
std::size_t length = 0;
716749
const bool build_absolute_path = flags & DYNAMIC_LINK_BUILD_ABSOLUTE_PATH;
717750
if (build_absolute_path) {
718751
length = abs_path( library, absolute_path, len );
719-
if (length > len) {
720-
DYNAMIC_LINK_WARNING( dl_buff_too_small );
721-
return nullptr;
722-
} else if (length == 0) {
752+
if (length == 0) {
723753
// length == 0 means failing of init_ap_data so the warning has already been issued.
754+
free(absolute_path);
755+
absolute_path = NULL;
724756
return nullptr;
725757
} else if (!file_exists(absolute_path)) {
726758
// Path to a file has been built manually. It is not proven to exist however.
727759
DYNAMIC_LINK_WARNING( dl_lib_not_found, absolute_path, dlerror() );
760+
free(absolute_path);
761+
absolute_path = NULL;
728762
return nullptr;
729763
}
730764
path = absolute_path;
731765
}
732766
#if _WIN32
733767
#if !__TBB_SKIP_DEPENDENCY_SIGNATURE_VERIFICATION
734768
if (!build_absolute_path) { // Get the path if it is not yet built
735-
length = get_module_path(absolute_path, len, library);
769+
length = get_module_path(absolute_path, (unsigned)len, library);
736770
if (length == 0) {
737771
DYNAMIC_LINK_WARNING( dl_lib_not_found, path, dlerror() );
772+
free(absolute_path);
773+
absolute_path = NULL;
738774
return library_handle;
739775
} else if (length >= len) { // The buffer length was insufficient
740776
DYNAMIC_LINK_WARNING( dl_buff_too_small );
777+
free(absolute_path);
778+
absolute_path = NULL;
741779
return library_handle;
742780
}
743781
length += 1; // Count terminating NULL character as part of string length
744782
path = absolute_path;
745783
}
746784

747-
if (!has_valid_signature(path, length))
785+
if (!has_valid_signature(path, length)) {
786+
free(absolute_path);
787+
absolute_path = NULL;
748788
return library_handle; // Warning (if any) has already been reported
789+
}
749790
#endif /* !__TBB_SKIP_DEPENDENCY_SIGNATURE_VERIFICATION */
750791
// Prevent Windows from displaying silly message boxes if it fails to load library
751792
// (e.g. because of MS runtime problems - one of those crazy manifest related ones)
@@ -764,6 +805,8 @@ namespace r1 {
764805
}
765806
} else
766807
DYNAMIC_LINK_WARNING( dl_lib_not_found, path, dlerror() );
808+
free(absolute_path);
809+
absolute_path = NULL;
767810
#endif /* __TBB_DYNAMIC_LOAD_ENABLED */
768811
return library_handle;
769812
}

src/tbb/dynamic_link.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
/*
22
Copyright (c) 2005-2025 Intel Corporation
3+
Copyright (c) 2026 UXL Foundation Contributors
34
45
Licensed under the Apache License, Version 2.0 (the "License");
56
you may not use this file except in compliance with the License.
@@ -132,8 +133,7 @@ enum dynamic_link_error_t : int {
132133
// System call returned error status
133134
dl_sys_fail, // char const * func, dlerr_t err
134135

135-
// Internal intermediate buffer is too small, consider setting PATH_MAX
136-
// macro to a larger value
136+
// Internal intermediate buffer is too small
137137
dl_buff_too_small, // none
138138

139139
// An error during library unload

src/tbb/tools_api/ittnotify_static.c

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,6 @@
2020
#include "ittnotify_config.h"
2121

2222
#if ITT_PLATFORM==ITT_PLATFORM_WIN
23-
#if !defined(PATH_MAX)
24-
#define PATH_MAX 512
25-
#endif
2623
#else /* ITT_PLATFORM!=ITT_PLATFORM_WIN */
2724
#include <limits.h>
2825
#include <dlfcn.h>

0 commit comments

Comments
 (0)