Skip to content

Commit a418923

Browse files
committed
Added input validation to model load
1 parent 87f6f2a commit a418923

File tree

3 files changed

+349
-114
lines changed

3 files changed

+349
-114
lines changed

src/pb_utils.cc

Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,12 +26,20 @@
2626

2727
#include "pb_utils.h"
2828

29+
#include <sys/stat.h>
30+
#include <fstream>
31+
2932
#ifdef _WIN32
3033
#include <windows.h>
3134

3235
#include <algorithm>
3336
#else
3437
#include <dlfcn.h>
38+
#include <unistd.h>
39+
#endif
40+
41+
#ifndef _WIN32
42+
extern char **environ;
3543
#endif
3644

3745

@@ -315,6 +323,42 @@ WrapTritonErrorInSharedPtr(TRITONSERVER_Error* error)
315323
}
316324
#endif // NOT TRITON_PB_STUB
317325

326+
bool IsValidIdentifier(const std::string& input) {
327+
if (input.empty()) {
328+
return false;
329+
}
330+
331+
// Check for invalid characters
332+
if (input.find_first_of(INVALID_CHARS) != std::string::npos) {
333+
return false;
334+
}
335+
336+
return true;
337+
}
338+
339+
bool IsValidPath(const std::string& path) {
340+
if (path.empty()) {
341+
return false;
342+
}
343+
344+
// Must be absolute path
345+
if (path[0] != '/') {
346+
return false;
347+
}
348+
349+
return true;
350+
}
351+
352+
bool IsExecutableFile(const std::string& filepath) {
353+
struct stat file_stat;
354+
if (stat(filepath.c_str(), &file_stat) != 0) {
355+
return false;
356+
}
357+
358+
// Check if it's a regular file and executable by owner
359+
return S_ISREG(file_stat.st_mode) && (file_stat.st_mode & S_IXUSR);
360+
}
361+
318362
std::string
319363
GenerateUUID()
320364
{
@@ -323,4 +367,95 @@ GenerateUUID()
323367
return boost::uuids::to_string(uuid);
324368
}
325369

370+
// Helper function to parse environment variables from activation script
371+
std::map<std::string, std::string>
372+
ParseActivationScript(const std::string& activate_path) {
373+
std::map<std::string, std::string> env_vars;
374+
375+
// Read the current environment as baseline
376+
#ifndef _WIN32
377+
if (environ != nullptr) {
378+
for (char **env = environ; *env != nullptr; env++) {
379+
std::string env_str(*env);
380+
size_t eq_pos = env_str.find('=');
381+
if (eq_pos != std::string::npos) {
382+
std::string key = env_str.substr(0, eq_pos);
383+
std::string value = env_str.substr(eq_pos + 1);
384+
env_vars[key] = value;
385+
}
386+
}
387+
}
388+
#endif
389+
390+
// Parse activation script for environment changes
391+
std::ifstream activate_file(activate_path);
392+
if (!activate_file.is_open()) {
393+
return env_vars; // Return current environment if can't read activation script
394+
}
395+
396+
std::string line;
397+
while (std::getline(activate_file, line)) {
398+
// Look for export statements or direct assignments
399+
if (line.find("export ") == 0) {
400+
// Handle: export VAR=value
401+
line = line.substr(7); // Remove "export "
402+
}
403+
404+
size_t eq_pos = line.find('=');
405+
if (eq_pos != std::string::npos && line[0] != '#') {
406+
std::string key = line.substr(0, eq_pos);
407+
std::string value = line.substr(eq_pos + 1);
408+
409+
// Remove quotes if present
410+
if (value.size() >= 2 &&
411+
((value[0] == '"' && value.back() == '"') ||
412+
(value[0] == '\'' && value.back() == '\''))) {
413+
value = value.substr(1, value.size() - 2);
414+
}
415+
416+
// Handle variable substitution for common cases
417+
if (value.find("$PATH") != std::string::npos) {
418+
size_t pos = value.find("$PATH");
419+
value.replace(pos, 5, env_vars["PATH"]);
420+
}
421+
if (value.find("$LD_LIBRARY_PATH") != std::string::npos) {
422+
size_t pos = value.find("$LD_LIBRARY_PATH");
423+
value.replace(pos, 16, env_vars["LD_LIBRARY_PATH"]);
424+
}
425+
426+
env_vars[key] = value;
427+
}
428+
}
429+
430+
return env_vars;
431+
}
432+
433+
// Helper function to prepare environment array for execve
434+
std::pair<std::vector<std::string>, std::vector<char*>>
435+
PrepareEnvironment(const std::map<std::string, std::string>& env_vars,
436+
const std::string& additional_lib_path) {
437+
438+
std::vector<std::string> env_strings;
439+
std::vector<char*> env_array;
440+
441+
for (const auto& [key, value] : env_vars) {
442+
std::string env_string;
443+
if (key == "LD_LIBRARY_PATH" && !additional_lib_path.empty()) {
444+
// Prepend the additional library path
445+
env_string = key + "=" + additional_lib_path + ":" + value;
446+
} else {
447+
env_string = key + "=" + value;
448+
}
449+
env_strings.push_back(env_string);
450+
}
451+
452+
// Convert to char* array
453+
for (auto& env_str : env_strings) {
454+
env_array.push_back(const_cast<char*>(env_str.c_str()));
455+
}
456+
env_array.push_back(nullptr);
457+
458+
return std::make_pair(std::move(env_strings), std::move(env_array));
459+
}
460+
326461
}}} // namespace triton::backend::python

src/pb_utils.h

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,10 +36,12 @@
3636
#include <boost/uuid/uuid_generators.hpp>
3737
#include <boost/uuid/uuid_io.hpp>
3838
#include <climits>
39+
#include <map>
3940
#include <memory>
4041
#include <mutex>
4142
#include <string>
4243
#include <unordered_map>
44+
#include <utility>
4345
#include <vector>
4446

4547
#include "pb_exception.h"
@@ -341,11 +343,30 @@ bool IsUsingCUDAPool(
341343
// being retrieved from core that are not platform-agnostic.
342344
void SanitizePath(std::string& path);
343345

346+
// Invalid characters that are not allowed in user input
347+
constexpr const char* INVALID_CHARS = ";|&$`<>()[]{}\\\"'*?~#!";
348+
349+
// Validate that an identifier (model name, region name, etc.)
350+
bool IsValidIdentifier(const std::string& input);
351+
352+
// Validate that a path exists and is absolute
353+
bool IsValidPath(const std::string& path);
354+
355+
// Check if a file exists and is executable
356+
bool IsExecutableFile(const std::string& filepath);
357+
344358
#ifndef TRITON_PB_STUB
345359
std::shared_ptr<TRITONSERVER_Error*> WrapTritonErrorInSharedPtr(
346360
TRITONSERVER_Error* error);
347361
#endif
348362

349363
std::string GenerateUUID();
350364

365+
// Environment handling utilities for Python activation scripts
366+
std::map<std::string, std::string> ParseActivationScript(const std::string& activate_path);
367+
368+
std::pair<std::vector<std::string>, std::vector<char*>> PrepareEnvironment(
369+
const std::map<std::string, std::string>& env_vars,
370+
const std::string& additional_lib_path = "");
371+
351372
}}} // namespace triton::backend::python

0 commit comments

Comments
 (0)