Skip to content

Commit 72e169c

Browse files
committed
THRIFT-5932: compiler/cpp: bound saferealpath() output on Windows
The Windows fallback in saferealpath() still copies either the original path or the GetFullPathNameA() result into resolved_path with strcpy(), but the helper does not know the caller buffer size. Make saferealpath() size-aware, reject paths that do not fit the caller buffer, and keep the existing call sites using their fixed THRIFT_PATH_MAX storage. Signed-off-by: Pengpeng Hou <pengpeng@iscas.ac.cn>
1 parent 3b0ab4d commit 72e169c

File tree

1 file changed

+19
-10
lines changed

1 file changed

+19
-10
lines changed

compiler/cpp/src/thrift/main.cc

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
#include <stdio.h>
3333
#include <stdarg.h>
3434
#include <time.h>
35+
#include <cstring>
3536
#include <string>
3637
#include <algorithm>
3738
#include <sys/types.h>
@@ -164,27 +165,35 @@ bool g_generator_failure = false;
164165
* Win32 doesn't have realpath, so use fallback implementation in that case,
165166
* otherwise this just calls through to realpath
166167
*/
167-
char* saferealpath(const char* path, char* resolved_path) {
168+
char* saferealpath(const char* path, char* resolved_path, size_t resolved_path_size) {
168169
#ifdef _WIN32
169170
char buf[MAX_PATH];
170171
char* basename;
172+
const char* source;
173+
size_t source_len;
171174
DWORD len = GetFullPathNameA(path, MAX_PATH, buf, &basename);
172175
if (len == 0 || len > MAX_PATH - 1) {
173-
strcpy(resolved_path, path);
176+
source = path;
174177
} else {
175-
strcpy(resolved_path, buf);
178+
source = buf;
176179
}
177180

181+
source_len = strlen(source);
182+
if (source_len >= resolved_path_size) {
183+
return nullptr;
184+
}
185+
memcpy(resolved_path, source, source_len + 1);
186+
178187
// Replace backslashes with forward slashes so the
179188
// rest of the code behaves correctly.
180-
size_t resolved_len = strlen(resolved_path);
181-
for (size_t i = 0; i < resolved_len; i++) {
189+
for (size_t i = 0; i < source_len; i++) {
182190
if (resolved_path[i] == '\\') {
183191
resolved_path[i] = '/';
184192
}
185193
}
186194
return resolved_path;
187195
#else
196+
(void) resolved_path_size;
188197
return realpath(path, resolved_path);
189198
#endif
190199
}
@@ -337,7 +346,7 @@ string include_file(string filename) {
337346
// Realpath!
338347
char rp[THRIFT_PATH_MAX];
339348
// cppcheck-suppress uninitvar
340-
if (saferealpath(filename.c_str(), rp) == nullptr) {
349+
if (saferealpath(filename.c_str(), rp, THRIFT_PATH_MAX) == nullptr) {
341350
pwarning(0, "Cannot open include file %s\n", filename.c_str());
342351
return std::string();
343352
}
@@ -360,7 +369,7 @@ string include_file(string filename) {
360369
// Realpath!
361370
char rp[THRIFT_PATH_MAX];
362371
// cppcheck-suppress uninitvar
363-
if (saferealpath(sfilename.c_str(), rp) == nullptr) {
372+
if (saferealpath(sfilename.c_str(), rp, THRIFT_PATH_MAX) == nullptr) {
364373
continue;
365374
}
366375

@@ -1174,7 +1183,7 @@ int main(int argc, char** argv) {
11741183
char old_thrift_file_rp[THRIFT_PATH_MAX];
11751184

11761185
// cppcheck-suppress uninitvar
1177-
if (saferealpath(arg, old_thrift_file_rp) == nullptr) {
1186+
if (saferealpath(arg, old_thrift_file_rp, THRIFT_PATH_MAX) == nullptr) {
11781187
failure("Could not open input file with realpath: %s", arg);
11791188
}
11801189
old_input_file = string(old_thrift_file_rp);
@@ -1232,7 +1241,7 @@ int main(int argc, char** argv) {
12321241
usage();
12331242
}
12341243
// cppcheck-suppress uninitvar
1235-
if (saferealpath(argv[i], new_thrift_file_rp) == nullptr) {
1244+
if (saferealpath(argv[i], new_thrift_file_rp, THRIFT_PATH_MAX) == nullptr) {
12361245
failure("Could not open input file with realpath: %s", argv[i]);
12371246
}
12381247
string new_input_file(new_thrift_file_rp);
@@ -1258,7 +1267,7 @@ int main(int argc, char** argv) {
12581267
usage();
12591268
}
12601269
// cppcheck-suppress uninitvar
1261-
if (saferealpath(argv[i], rp) == nullptr) {
1270+
if (saferealpath(argv[i], rp, THRIFT_PATH_MAX) == nullptr) {
12621271
failure("Could not open input file with realpath: %s", argv[i]);
12631272
}
12641273
string input_file(rp);

0 commit comments

Comments
 (0)